@@ -155,13 +155,14 @@ int doSpecial(String funName, PTuple argv, Object kwds, @SuppressWarnings("unuse
155
155
@ Cached (value = "getChars(format)" , allowUncached = true , dimensions = 1 ) char [] chars ,
156
156
@ Cached ("createConvertArgNodes(cachedFormat)" ) ConvertArgNode [] convertArgNodes ,
157
157
@ Cached HashingCollectionNodes .LenNode kwdsLenNode ,
158
+ @ Cached SequenceStorageNodes .LenNode argvLenNode ,
158
159
@ Cached PRaiseNativeNode raiseNode ) {
159
160
try {
160
161
PDict kwdsDict = null ;
161
162
if (kwds != null && kwdsLenNode .execute ((PDict ) kwds ) != 0 ) {
162
163
kwdsDict = (PDict ) kwds ;
163
164
}
164
- doParsingExploded (funName , argv , kwdsDict , chars , kwdnames , varargs , nativeConext , convertArgNodes , raiseNode );
165
+ doParsingExploded (funName , argv , kwdsDict , chars , kwdnames , varargs , nativeConext , convertArgNodes , argvLenNode , raiseNode );
165
166
return 1 ;
166
167
} catch (InteropException | ParseArgumentsException e ) {
167
168
return 0 ;
@@ -173,6 +174,7 @@ int doSpecial(String funName, PTuple argv, Object kwds, @SuppressWarnings("unuse
173
174
int doGeneric (String funName , PTuple argv , Object kwds , String format , Object kwdnames , Object varargs , CExtContext nativeContext ,
174
175
@ Cached ConvertArgNode convertArgNode ,
175
176
@ Cached HashingCollectionNodes .LenNode kwdsLenNode ,
177
+ @ Cached SequenceStorageNodes .LenNode argvLenNode ,
176
178
@ Cached PRaiseNativeNode raiseNode ) {
177
179
try {
178
180
char [] chars = getChars (format );
@@ -184,12 +186,21 @@ int doGeneric(String funName, PTuple argv, Object kwds, String format, Object kw
184
186
for (int i = 0 ; i < format .length (); i ++) {
185
187
state = convertArg (state , kwdsDict , chars , i , kwdnames , varargs , convertArgNode , raiseNode );
186
188
}
189
+ checkExcessArgs (argv , argvLenNode , state , raiseNode );
187
190
return 1 ;
188
191
} catch (InteropException | ParseArgumentsException e ) {
189
192
return 0 ;
190
193
}
191
194
}
192
195
196
+ private static void checkExcessArgs (PTuple argv , SequenceStorageNodes .LenNode argvLenNode , ParserState state , PRaiseNativeNode raiseNode ) {
197
+ int argvLen = argvLenNode .execute (argv .getSequenceStorage ());
198
+ if (argvLen > state .v .argnum ) {
199
+ raiseNode .raiseIntWithoutFrame (0 , TypeError , ErrorMessages .EXPECTED_AT_MOST_D_ARGS_GOT_D , state .v .argnum , argvLen );
200
+ throw ParseArgumentsException .raise ();
201
+ }
202
+ }
203
+
193
204
@ Fallback
194
205
@ SuppressWarnings ("unused" )
195
206
int error (String funName , Object argv , Object kwds , Object format , Object kwdnames , Object varargs , CExtContext nativeContext ,
@@ -199,13 +210,14 @@ int error(String funName, Object argv, Object kwds, Object format, Object kwdnam
199
210
200
211
@ ExplodeLoop (kind = LoopExplosionKind .FULL_UNROLL_UNTIL_RETURN )
201
212
private static void doParsingExploded (String funName , PTuple argv , Object kwds , char [] chars , Object kwdnames , Object varargs , CExtContext nativeContext ,
202
- ConvertArgNode [] convertArgNodes , PRaiseNativeNode raiseNode )
213
+ ConvertArgNode [] convertArgNodes , SequenceStorageNodes . LenNode argvLenNode , PRaiseNativeNode raiseNode )
203
214
throws InteropException , ParseArgumentsException {
204
215
CompilerAsserts .partialEvaluationConstant (chars .length );
205
216
ParserState state = new ParserState (funName , new PositionalArgStack (argv , null ), nativeContext );
206
217
for (int i = 0 ; i < chars .length ; i ++) {
207
218
state = convertArg (state , kwds , chars , i , kwdnames , varargs , convertArgNodes [i ], raiseNode );
208
219
}
220
+ checkExcessArgs (argv , argvLenNode , state , raiseNode );
209
221
}
210
222
211
223
private static ParserState convertArg (ParserState state , Object kwds , char [] format , int format_idx , Object kwdnames , Object varargs , ConvertArgNode convertArgNode ,
0 commit comments