Skip to content

Commit 553dcda

Browse files
Correct errors
1 parent ee025cd commit 553dcda

6 files changed

Lines changed: 79 additions & 56 deletions

File tree

backend/shexstatements/shexfromcsv.py

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import csv
88
import re
99
from io import StringIO
10+
import os
1011

1112
from shexstatements.shexstatementsparser import ShExStatementLexerParser
1213

@@ -70,28 +71,46 @@ def generate_shex_from_csv(filepath, delim=",", skip_header=False, filename=True
7071
pattern = r'^\s*$'
7172
data = ""
7273
if filename:
73-
csvfile = open(filepath)
74-
csvreader = csv.reader(csvfile, delimiter=delim)
74+
normalized_path = os.path.normpath(filepath.strip())
75+
if not normalized_path:
76+
raise ValueError("Empty filename is not allowed")
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"
7596
else:
7697
# It's a multi-line string
7798
csvstring = StringIO(filepath)
7899
csvreader = csv.reader(csvstring, delimiter=delim)
79-
rowno = 0
80-
for row in csvreader:
81-
rowno = rowno + 1
82-
if skip_header and rowno == 1:
83-
continue
84-
line = ""
85-
for value in row:
86-
if value and not re.match(pattern, value):
87-
if not line:
88-
line = value
89-
else:
90-
line = line + "|" + value
91-
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"
92113
shexstatement = CSV.generate_shex_from_data_string(data)
93-
if filename:
94-
csvfile.close()
95114
except Exception as e:
96115
print("Unable to read file. Error: " + str(e))
97116
return shexstatement

shexstatements/application.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44
# SPDX-License-Identifier: GPL-3.0-or-later
55
#
6-
from flask import Flask, render_template, url_for, request, redirect
6+
from flask import Flask, render_template, request
77
from shexstatements.shexfromcsv import CSV
88
from shexstatements.shexfromspreadsheet import Spreadsheet
99
from os.path import splitext

shexstatements/shexfromapplprofilecsv.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
#
66

77
import csv
8-
import re
9-
from shexstatements.shexstatementsparser import ShExStatementLexerParser
108
from shexstatements.shexfromcsv import CSV
119

1210
"""

shexstatements/shexfromcsv.py

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

shexstatements/shexstatement.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
# SPDX-License-Identifier: GPL-3.0-or-later
55
#
66

7-
import re
8-
9-
107
class Type:
118
def __init__(self, name):
129
self.name = name[2:]
@@ -46,7 +43,7 @@ def __init__(self, value_list):
4643
self.value_list = value_list
4744

4845
def add(self, value):
49-
if(type(value) == Type):
46+
if isinstance(value, Type):
5047
self.value_list.append(value)
5148
else:
5249
raise Exception("Mixing of non-type values not allowed")
@@ -68,7 +65,7 @@ def __init__(self, value_list):
6865
self.value_list = value_list
6966

7067
def add(self, value):
71-
if(type(value) == Value):
68+
if isinstance(value, Value):
7269
self.value_list.append(value)
7370

7471
def get_value_list(self):
@@ -164,13 +161,13 @@ def generate_shex(self):
164161
else:
165162
combination.append(prop)
166163
combination.append(" ")
167-
if (type(value) == Node and str(value).startswith("@")):
164+
if isinstance(value, Node) and str(value).startswith("@"):
168165
value = "@<" + str(value)[1:] + ">"
169-
elif type(value) == NodeKind:
166+
elif isinstance(value, NodeKind):
170167
value = str(value)
171-
elif type(value) == Value or type(value) == ValueList:
168+
elif isinstance(value, (Value, ValueList)):
172169
value = "[ " + str(value) + " ]"
173-
elif type(value) == Type or type(value) == TypeList:
170+
elif isinstance(value, (Type, TypeList)):
174171
value = str(value)
175172
combination.append(value)
176173

shexstatements/shexstatementsparser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from ply import lex
88
from ply import yacc
99
from .errors import UnrecognizedCharacterError, ParserError
10-
from .shexstatement import Node, NodeKind, Value, ValueList, Type, TypeList, Cardinality, ShExStatement, ShExStatements
10+
from .shexstatement import Node, NodeKind, Value, ValueList, Type, TypeList, ShExStatement, ShExStatements
1111

1212

1313
class ShExStatementLexerParser(object):

0 commit comments

Comments
 (0)