@@ -36,7 +36,7 @@ def generate_shex_from_data_string(data):
3636 lexerparser = ShExStatementLexerParser ()
3737 lexerparser .build ()
3838 lexerparser .buildparser ()
39- tokens = lexerparser .input (data )
39+ lexerparser .input (data )
4040 result = lexerparser .parse (data )
4141 shexstatement = result .generate_shex ()
4242 except Exception as e :
@@ -70,38 +70,47 @@ def generate_shex_from_csv(filepath, delim=",", skip_header=False, filename=True
7070 pattern = r'^\s*$'
7171 data = ""
7272 if filename :
73- # Validate and normalize the file path to avoid path traversal
74- normalized_path = os .path .normpath (filepath )
75- # Reject absolute paths
76- if os .path .isabs (normalized_path ):
77- raise ValueError ("Absolute paths are not allowed" )
78- # Only allow simple filenames without directory components
79- if os .path .sep in normalized_path or (os .path .altsep and os .path .altsep in normalized_path ):
80- raise ValueError ("Directory separators are not allowed in filename" )
73+ # Validate and normalize the path while allowing relative subdirectories.
74+ normalized_path = os .path .normpath (filepath .strip ())
8175 if not normalized_path :
8276 raise ValueError ("Empty filename is not allowed" )
83- csvfile = open (normalized_path , 'r' )
84- csvreader = csv .reader (csvfile , delimiter = delim )
77+ if os .path .isabs (normalized_path ):
78+ raise ValueError ("Absolute paths are not allowed" )
79+ if normalized_path == ".." or normalized_path .startswith (".." + os .path .sep ):
80+ raise ValueError ("Path traversal is not allowed" )
81+ with open (normalized_path , "r" ) as csvfile :
82+ csvreader = csv .reader (csvfile , delimiter = delim )
83+ rowno = 0
84+ for row in csvreader :
85+ rowno = rowno + 1
86+ if skip_header and rowno == 1 :
87+ continue
88+ line = ""
89+ for value in row :
90+ if value and not re .match (pattern , value ):
91+ if not line :
92+ line = value
93+ else :
94+ line = line + "|" + value
95+ data = data + line + "\n "
8596 else :
8697 # It's a multi-line string
8798 csvstring = StringIO (filepath )
8899 csvreader = csv .reader (csvstring , delimiter = delim )
89- rowno = 0
90- for row in csvreader :
91- rowno = rowno + 1
92- if skip_header and rowno == 1 :
93- continue
94- line = ""
95- for value in row :
96- if value and not re .match (pattern , value ):
97- if not line :
98- line = value
99- else :
100- line = line + "|" + value
101- data = data + line + "\n "
100+ rowno = 0
101+ for row in csvreader :
102+ rowno = rowno + 1
103+ if skip_header and rowno == 1 :
104+ continue
105+ line = ""
106+ for value in row :
107+ if value and not re .match (pattern , value ):
108+ if not line :
109+ line = value
110+ else :
111+ line = line + "|" + value
112+ data = data + line + "\n "
102113 shexstatement = CSV .generate_shex_from_data_string (data )
103- if filename :
104- csvfile .close ()
105114 except Exception as e :
106115 print ("Unable to read file. Error: " + str (e ))
107116 return shexstatement
0 commit comments