@@ -120,55 +120,76 @@ def scanner(scan): # type: (Text) -> List[int]
120120 return None
121121
122122
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+
126128 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 ('\\ "' , '"' )
131133
132134 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 ) )
139141 else :
140142 try :
141- key = int (m . group ( 0 ) [1 :- 1 ])
143+ key = int (next_segment_str [1 :- 1 ])
142144 except ValueError as v :
143145 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+
148151 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 ))
152155 else :
153- return obj
156+ return current_value
154157
155158
156159def evaluator (ex , jslib , obj , fullJS = False , timeout = None , force_docker_pull = False , debug = False , js_console = False ):
157160 # type: (Text, Text, Dict[Text, Any], bool, int, bool, bool, bool) -> JSON
158161 m = param_re .match (ex )
162+
163+ expression_parse_exception = None
164+ expression_parse_succeeded = False
165+
159166 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" :
161171 return None
162172 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 :
167183 return sandboxjs .execjs (ex , jslib , timeout = timeout , force_docker_pull = force_docker_pull , debug = debug , js_console = js_console )
168184 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 )
172193
173194
174195def interpolate (scan , rootvars ,
0 commit comments