@@ -193,28 +193,58 @@ FormatSpecifier parseSpecifier() {
193
193
spec .widthFromArg = true ; // Means "has custom separator"
194
194
advance (); // consume 'v'
195
195
196
+ System .err .println ("DEBUG Parser: Parsed %*v, next char: '" + current () + "'" );
197
+
196
198
// Now check for width after %*v
197
199
if (match ('*' )) {
200
+ System .err .println ("DEBUG Parser: Found * after %*v" );
198
201
// Check for invalid positional after %*v*
199
202
checkpoint = pos ;
200
203
Integer posParam = parseNumber ();
201
- if (posParam != null && peek (0 ) == '$' ) {
204
+ System .err .println ("DEBUG Parser: After %*v*, number=" + posParam + ", current='" + current () + "'" );
205
+
206
+ if (posParam != null && match ('$' )) {
207
+ System .err .println ("DEBUG Parser: Detected invalid %*v*N$ pattern" );
202
208
// %*v*999$ is invalid
203
- advance (); // consume $
204
- while (!isAtEnd () && !Character .isLetter (current ())) {
205
- advance ();
206
- }
209
+
210
+ // Continue parsing to get the conversion character
207
211
if (!isAtEnd ()) {
208
212
spec .conversionChar = current ();
209
213
advance ();
210
214
}
215
+
216
+ spec .isValid = false ;
217
+ spec .errorMessage = "INVALID" ;
218
+ spec .endPos = pos ;
219
+ spec .raw = input .substring (spec .startPos , spec .endPos );
220
+ System .err .println ("DEBUG Parser: Returning invalid spec: " + spec .raw );
221
+ return spec ;
222
+ } else if (posParam != null ) {
223
+ // ADDITIONAL CHANGE: Handle case where we have number but no $
224
+ // This is still invalid - don't reset position
225
+ System .err .println ("DEBUG Parser: Found number after %*v* but no $ - treating as invalid" );
226
+
227
+ // The number is part of the format, continue to find conversion char
228
+ // Current position is after the number
229
+ if (!isAtEnd ()) {
230
+ // Skip any backslashes or other characters until we find a letter
231
+ while (!isAtEnd () && !Character .isLetter (current ())) {
232
+ advance ();
233
+ }
234
+ if (!isAtEnd ()) {
235
+ spec .conversionChar = current ();
236
+ advance ();
237
+ }
238
+ }
239
+
211
240
spec .isValid = false ;
212
241
spec .errorMessage = "INVALID" ;
213
242
spec .endPos = pos ;
214
243
spec .raw = input .substring (spec .startPos , spec .endPos );
244
+ System .err .println ("DEBUG Parser: Returning invalid spec: " + spec .raw );
215
245
return spec ;
216
246
} else {
217
- pos = checkpoint ; // Reset
247
+ pos = checkpoint ; // Reset only if no number was found
218
248
spec .precisionFromArg = true ; // HACK: means second *
219
249
}
220
250
} else {
@@ -311,14 +341,44 @@ FormatSpecifier parseSpecifier() {
311
341
}
312
342
}
313
343
314
- // 7. Parse conversion character
344
+ // 7. Parse conversion character
315
345
if (isAtEnd ()) {
316
346
spec .isValid = false ;
317
347
spec .errorMessage = "MISSING" ;
318
348
} else {
319
- spec . conversionChar = current ();
349
+ char firstChar = current ();
320
350
advance ();
321
- // System.err.println("DEBUG: Parsed conversion char '" + spec.conversionChar + "'");
351
+
352
+ // Check if this might be part of a positional parameter
353
+ if (Character .isDigit (firstChar ) && !isAtEnd ()) {
354
+ // Look ahead to see if we have more digits and a $
355
+ int checkPos = pos ;
356
+ while (!isAtEnd () && Character .isDigit (current ())) {
357
+ advance ();
358
+ }
359
+
360
+ if (!isAtEnd () && current () == '$' ) {
361
+ // This is an invalid positional parameter at the conversion position
362
+ advance (); // consume $
363
+
364
+ // Get the actual conversion character
365
+ if (!isAtEnd ()) {
366
+ spec .conversionChar = current ();
367
+ advance ();
368
+ } else {
369
+ spec .conversionChar = firstChar ; // Use the first digit if nothing follows
370
+ }
371
+
372
+ spec .isValid = false ;
373
+ spec .errorMessage = "INVALID" ;
374
+ } else {
375
+ // Not a positional parameter, just use the first character
376
+ pos = checkPos ; // Reset to after first char
377
+ spec .conversionChar = firstChar ;
378
+ }
379
+ } else {
380
+ spec .conversionChar = firstChar ;
381
+ }
322
382
}
323
383
324
384
spec .endPos = pos ;
@@ -500,4 +560,4 @@ void validateFlags(FormatSpecifier spec) {
500
560
}
501
561
}
502
562
}
503
- }
563
+ }
0 commit comments