php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29733 [PATCH] printf handles repeated placeholders wrong
Submitted: 2004-08-18 14:46 UTC Modified: 2005-01-26 01:03 UTC
From: bugs dot php dot net at bluetwanger dot de Assigned:
Status: Closed Package: Strings related
PHP Version: 4CVS, 5CVS (2004-12-12) OS: *
Private report: No CVE-ID:
 [2004-08-18 14:46 UTC] bugs dot php dot net at bluetwanger dot de
Description:
------------
printf('%s - %s %s %3$s %2$s', 1, 2, 3);

complains:

Warning: printf(): Too few arguments in /home/bertheau/printf.php on line 2

printf('%s - %s %s %3$s %2$s', 1, 2, 3, 4);

does not complain and prints:

1 - 2 3 3 2

I expect the first version to not complain and print what the second version prints.



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-08-27 14:30 UTC] bugs dot php dot net at bluetwanger dot de
Here's a patch:

--- ext/standard/formatted_print.c.orig 2004-07-18 19:28:04.000000000 +0200
+++ ext/standard/formatted_print.c      2004-08-27 14:23:07.580732341 +0200
@@ -537,12 +537,6 @@
                        php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC);
                        inpos += 2;
                } else {
-                       if (currarg >= argc && format[inpos + 1] != '%') {
-                               efree(result);
-                               efree(args);
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments");
-                               return NULL;
-                       }
                        /* starting a new format specifier, reset variables */
                        alignment = ALIGN_RIGHT;
                        adjusting = 0;
@@ -574,13 +568,6 @@
  
                                argnum += format_offset;
  
-                               if (argnum >= argc) {
-                                       efree(result);
-                                       efree(args);
-                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments");
-                                       return NULL;
-                               }
-
                                /* after argnum comes modifiers */
                                PRINTF_DEBUG(("sprintf: looking for modifiers\n"
                                                          "sprintf: now looking at '%c', inpos=%d\n",
@@ -635,6 +622,13 @@
                                argnum = currarg++ + format_offset;
                        }
  

+            if (argnum >= argc) {
+                efree(result);
+                efree(args);
+                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments");
+                return NULL;
+            }
+
                        if (format[inpos] == 'l') {
                                inpos++;
                        }

Let's see if the line breaks survive.

It basically removes the bogus (format[inpos + 1] != '%' will always be true there) arg number check and moves the right one outside the special case for "complicated" format specifiers.
 [2004-08-27 14:36 UTC] bugs dot php dot net at bluetwanger dot de
Here's a link: http://www.bluetwanger.de/~mbertheau/formatted_print.c.patch

You make it really hard to submit a patch. This bug thing has no provision for attaching a file and you have to strain a lot to get at an email address of a developer mailing list.
 [2004-09-30 16:42 UTC] danielc at analysisandsolutions dot com
Note, the error only happens when mixing numbered and non-numberd directives.  Tweaking the example from the original bug report to use only numbered directives eliminates the error:

   printf('%1$s - %2$s %3$s %3$s %2$s', 1, 2, 3);
 [2004-10-05 17:50 UTC] bugs dot php dot net at afdelingp dot dk
The bug is also in PHP 4.3.

The problem is that the original check for too-few-arguments was left in the code when I implemented argnum swapping. Your patch (moving the check to the bottom instead of having two checks) fixes this, and should be applied to PHP 4.3 too.

Embarrassing :-)
 [2005-01-26 01:03 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 20:02:01 2014 UTC