@@ -155,13 +155,14 @@ int doSpecial(String funName, PTuple argv, Object kwds, @SuppressWarnings("unuse
155155 @ Cached (value = "getChars(format)" , allowUncached = true , dimensions = 1 ) char [] chars ,
156156 @ Cached ("createConvertArgNodes(cachedFormat)" ) ConvertArgNode [] convertArgNodes ,
157157 @ Cached HashingCollectionNodes .LenNode kwdsLenNode ,
158+ @ Cached SequenceStorageNodes .LenNode argvLenNode ,
158159 @ Cached PRaiseNativeNode raiseNode ) {
159160 try {
160161 PDict kwdsDict = null ;
161162 if (kwds != null && kwdsLenNode .execute ((PDict ) kwds ) != 0 ) {
162163 kwdsDict = (PDict ) kwds ;
163164 }
164- doParsingExploded (funName , argv , kwdsDict , chars , kwdnames , varargs , nativeConext , convertArgNodes , raiseNode );
165+ doParsingExploded (funName , argv , kwdsDict , chars , kwdnames , varargs , nativeConext , convertArgNodes , argvLenNode , raiseNode );
165166 return 1 ;
166167 } catch (InteropException | ParseArgumentsException e ) {
167168 return 0 ;
@@ -173,6 +174,7 @@ int doSpecial(String funName, PTuple argv, Object kwds, @SuppressWarnings("unuse
173174 int doGeneric (String funName , PTuple argv , Object kwds , String format , Object kwdnames , Object varargs , CExtContext nativeContext ,
174175 @ Cached ConvertArgNode convertArgNode ,
175176 @ Cached HashingCollectionNodes .LenNode kwdsLenNode ,
177+ @ Cached SequenceStorageNodes .LenNode argvLenNode ,
176178 @ Cached PRaiseNativeNode raiseNode ) {
177179 try {
178180 char [] chars = getChars (format );
@@ -184,12 +186,21 @@ int doGeneric(String funName, PTuple argv, Object kwds, String format, Object kw
184186 for (int i = 0 ; i < format .length (); i ++) {
185187 state = convertArg (state , kwdsDict , chars , i , kwdnames , varargs , convertArgNode , raiseNode );
186188 }
189+ checkExcessArgs (argv , argvLenNode , state , raiseNode );
187190 return 1 ;
188191 } catch (InteropException | ParseArgumentsException e ) {
189192 return 0 ;
190193 }
191194 }
192195
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+
193204 @ Fallback
194205 @ SuppressWarnings ("unused" )
195206 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
199210
200211 @ ExplodeLoop (kind = LoopExplosionKind .FULL_UNROLL_UNTIL_RETURN )
201212 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 )
203214 throws InteropException , ParseArgumentsException {
204215 CompilerAsserts .partialEvaluationConstant (chars .length );
205216 ParserState state = new ParserState (funName , new PositionalArgStack (argv , null ), nativeContext );
206217 for (int i = 0 ; i < chars .length ; i ++) {
207218 state = convertArg (state , kwds , chars , i , kwdnames , varargs , convertArgNodes [i ], raiseNode );
208219 }
220+ checkExcessArgs (argv , argvLenNode , state , raiseNode );
209221 }
210222
211223 private static ParserState convertArg (ParserState state , Object kwds , char [] format , int format_idx , Object kwdnames , Object varargs , ConvertArgNode convertArgNode ,
0 commit comments