7777def safe_name (value , context ):
7878 """
7979 Validates that the input string does not contain characters dangerous
80- for filesystem paths or shell command injection.
80+ for simple names (labels, filenames without paths).
81+ Use safe_path() for validating directory/file paths.
8182 """
8283 if not value :
8384 raise ValueError (f"{ context } cannot be empty" )
@@ -86,22 +87,36 @@ def safe_name(value, context):
8687 raise ValueError (f"Unsafe { context } : '{ value } ' contains illegal characters." )
8788 return value
8889
89- MKCONCORE_VER = "22-09-18"
90-
91- SCRIPT_DIR = os .path .dirname (os .path .abspath (__file__ ))
92-
93- def _resolve_concore_path ():
94- script_concore = os .path .join (SCRIPT_DIR , "concore.py" )
95- if os .path .exists (script_concore ):
96- return SCRIPT_DIR
97- cwd_concore = os .path .join (os .getcwd (), "concore.py" )
98- if os .path .exists (cwd_concore ):
99- return os .getcwd ()
100- return SCRIPT_DIR
101-
102- GRAPHML_FILE = sys .argv [1 ]
103- TRIMMED_LOGS = True
104- CONCOREPATH = _resolve_concore_path ()
90+ def safe_path (value , context ):
91+ """
92+ Validates that a path string does not contain characters dangerous for shell command injection.
93+ Unlike safe_name(), this allows path separators (/ and \) but still blocks dangerous shell metacharacters.
94+ """
95+ if not value :
96+ raise ValueError (f"{ context } cannot be empty" )
97+ # Allow path separators but block control characters and shell metacharacters
98+ # Blocks: control chars, *, ?, <, >, |, ;, &, $, `, ', ", (, )
99+ # Allows: /, \, -, _, ., alphanumeric, spaces, :
100+ if re .search (r'[\x00-\x1F\x7F*?"<>|;&`$\'()]' , value ):
101+ raise ValueError (f"Unsafe { context } : '{ value } ' contains illegal characters." )
102+ return value
103+
104+ MKCONCORE_VER = "22-09-18"
105+
106+ SCRIPT_DIR = os .path .dirname (os .path .abspath (__file__ ))
107+
108+ def _resolve_concore_path ():
109+ script_concore = os .path .join (SCRIPT_DIR , "concore.py" )
110+ if os .path .exists (script_concore ):
111+ return SCRIPT_DIR
112+ cwd_concore = os .path .join (os .getcwd (), "concore.py" )
113+ if os .path .exists (cwd_concore ):
114+ return os .getcwd ()
115+ return SCRIPT_DIR
116+
117+ GRAPHML_FILE = sys .argv [1 ]
118+ TRIMMED_LOGS = True
119+ CONCOREPATH = _resolve_concore_path ()
105120CPPWIN = "g++" #Windows C++ 6/22/21
106121CPPEXE = "g++" #Ubuntu/macOS C++ 6/22/21
107122VWIN = "iverilog" #Windows verilog 6/25/21
@@ -142,8 +157,9 @@ def _resolve_concore_path():
142157sourcedir = sys .argv [2 ]
143158outdir = sys .argv [3 ]
144159
145- # Validate outdir argument
146- safe_name (outdir , "Output directory argument" )
160+ # Validate path arguments
161+ safe_path (outdir , "Output directory argument" )
162+ safe_path (sourcedir , "Source directory argument" )
147163
148164if not os .path .isdir (sourcedir ):
149165 logging .error (f"{ sourcedir } does not exist" )
0 commit comments