@@ -120,55 +120,76 @@ def scanner(scan): # type: (Text) -> List[int]
120
120
return None
121
121
122
122
123
- def next_seg (remain , obj ): # type: (Text, Any) -> Any
124
- if remain :
125
- m = segment_re .match (remain )
123
+ def next_seg (parsed_string , remaining_string , current_value ): # type: (Text, Text, Any) -> Any
124
+ if remaining_string :
125
+ m = segment_re .match (remaining_string )
126
+ next_segment_str = m .group (0 )
127
+
126
128
key = None # type: Union[Text, int]
127
- if m . group ( 0 ) [0 ] == '.' :
128
- key = m . group ( 0 ) [1 :]
129
- elif m . group ( 0 ) [1 ] in ("'" , '"' ):
130
- key = m . group ( 0 ) [2 :- 2 ].replace ("\\ '" , "'" ).replace ('\\ "' , '"' )
129
+ if next_segment_str [0 ] == '.' :
130
+ key = next_segment_str [1 :]
131
+ elif next_segment_str [1 ] in ("'" , '"' ):
132
+ key = next_segment_str [2 :- 2 ].replace ("\\ '" , "'" ).replace ('\\ "' , '"' )
131
133
132
134
if key :
133
- if isinstance (obj , list ) and key == "length" and not remain [m .end (0 ):]:
134
- return len (obj )
135
- if not isinstance (obj , dict ):
136
- raise WorkflowException (" is a %s, cannot index on string '%s'" % (type (obj ).__name__ , key ))
137
- if key not in obj :
138
- raise WorkflowException (" does not contain key '%s'" % key )
135
+ if isinstance (current_value , list ) and key == "length" and not remaining_string [m .end (0 ):]:
136
+ return len (current_value )
137
+ if not isinstance (current_value , dict ):
138
+ raise WorkflowException ("%s is a %s, cannot index on string '%s'" % (parsed_string , type (current_value ).__name__ , key ))
139
+ if key not in current_value :
140
+ raise WorkflowException ("%s does not contain key '%s'" % ( parsed_string , key ) )
139
141
else :
140
142
try :
141
- key = int (m . group ( 0 ) [1 :- 1 ])
143
+ key = int (next_segment_str [1 :- 1 ])
142
144
except ValueError as v :
143
145
raise WorkflowException (u (str (v )))
144
- if not isinstance (obj , list ):
145
- raise WorkflowException (" is a %s, cannot index on int '%s'" % (type (obj ).__name__ , key ))
146
- if key >= len (obj ):
147
- raise WorkflowException (" list index %i out of range" % key )
146
+ if not isinstance (current_value , list ):
147
+ raise WorkflowException ("%s is a %s, cannot index on int '%s'" % (parsed_string , type (current_value ).__name__ , key ))
148
+ if key >= len (current_value ):
149
+ raise WorkflowException ("%s list index %i out of range" % (parsed_string , key ))
150
+
148
151
try :
149
- return next_seg (remain [m .end (0 ):], obj [key ])
150
- except WorkflowException as w :
151
- raise WorkflowException ("%s%s" % (m . group ( 0 ), w ))
152
+ return next_seg (parsed_string + remaining_string , remaining_string [m .end (0 ):], current_value [key ])
153
+ except KeyError :
154
+ raise WorkflowException ("%s doesn't have property %s" % (parsed_string , key ))
152
155
else :
153
- return obj
156
+ return current_value
154
157
155
158
156
159
def evaluator (ex , jslib , obj , fullJS = False , timeout = None , force_docker_pull = False , debug = False , js_console = False ):
157
160
# type: (Text, Text, Dict[Text, Any], bool, int, bool, bool, bool) -> JSON
158
161
m = param_re .match (ex )
162
+
163
+ expression_parse_exception = None
164
+ expression_parse_succeeded = False
165
+
159
166
if m :
160
- if m .end (1 )+ 1 == len (ex ) and m .group (1 ) == "null" :
167
+ first_symbol = m .group (1 )
168
+ first_symbol_end = m .end (1 )
169
+
170
+ if first_symbol_end + 1 == len (ex ) and first_symbol == "null" :
161
171
return None
162
172
try :
163
- return next_seg (m .group (0 )[m .end (1 ) - m .start (0 ):- 1 ], obj [m .group (1 )])
164
- except Exception as w :
165
- raise WorkflowException ("%s%s" % (m .group (1 ), w ))
166
- elif fullJS :
173
+ if obj .get (first_symbol ) is None :
174
+ raise WorkflowException ("%s is not defined" % first_symbol )
175
+
176
+ return next_seg (first_symbol , ex [first_symbol_end :- 1 ], obj [first_symbol ])
177
+ except WorkflowException as w :
178
+ expression_parse_exception = w
179
+ else :
180
+ expression_parse_succeeded = True
181
+
182
+ if fullJS and not expression_parse_succeeded :
167
183
return sandboxjs .execjs (ex , jslib , timeout = timeout , force_docker_pull = force_docker_pull , debug = debug , js_console = js_console )
168
184
else :
169
- raise sandboxjs .JavascriptException (
170
- "Syntax error in parameter reference '%s' or used Javascript code without specifying InlineJavascriptRequirement." ,
171
- ex )
185
+ if expression_parse_exception is not None :
186
+ raise sandboxjs .JavascriptException (
187
+ "Syntax error in parameter reference '%s': %s. This could be due to using Javascript code without specifying InlineJavascriptRequirement." % \
188
+ (ex [1 :- 1 ], expression_parse_exception ))
189
+ else :
190
+ raise sandboxjs .JavascriptException (
191
+ "Syntax error in parameter reference '%s'. This could be due to using Javascript code without specifying InlineJavascriptRequirement." % \
192
+ ex )
172
193
173
194
174
195
def interpolate (scan , rootvars ,
0 commit comments