]> granicus.if.org Git - php/commitdiff
unpack() function accepts an additional optional argument $offset.
authorDmitry Stogov <dmitry@zend.com>
Thu, 3 Mar 2016 10:49:45 +0000 (13:49 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 3 Mar 2016 10:49:45 +0000 (13:49 +0300)
NEWS
UPGRADING
ext/standard/pack.c
ext/standard/tests/strings/unpack_error.phpt
ext/standard/tests/strings/unpack_offset.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index b0ee6b88e509e6bca5c1413f45652a697f433b72..0aff059ebcc0f9c469078110d73e5457ebd83389 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -53,5 +53,6 @@ PHP                                                                        NEWS
     (Ilia) (Julien)
   . Implemented FR #69359 (Provide a way to fetch the current environment
     variables). (Ferenc)
+  . unpack() function accepts an additional optional argument $offset. (Dmitry)
 
 <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
index 7865df65e54c9a121f9a402e721ecd98444e45af..94cea6f9a200d29e0e59533a166816f7ed7e9083 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -63,6 +63,9 @@ PHP 7.1 UPGRADE NOTES
   pg_fetch_row().
 - pg_select() accepts 4th optional result type parameter like pg_fetch_row().
 - parse_url() is more restrictive now and supports RFC3986.
+- unpack() accepts an additional optional $offset argument. '@' format code
+  (that specifes an absolute position) is applyed to input data after
+  the $offset argument.
 
 ========================================
 6. New Functions
index a24ee69ad291cb047ee84bfb9e484ff5f930e1f5..1d353d1743d5f2f6369c2abfd43a547f400c046c 100644 (file)
@@ -551,9 +551,10 @@ PHP_FUNCTION(unpack)
        zend_string *formatarg, *inputarg;
        zend_long formatlen, inputpos, inputlen;
        int i;
+       zend_long offset = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &formatarg,
-               &inputarg) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &formatarg,
+               &inputarg, &offset) == FAILURE) {
                return;
        }
 
@@ -563,6 +564,14 @@ PHP_FUNCTION(unpack)
        inputlen = ZSTR_LEN(inputarg);
        inputpos = 0;
 
+
+       if (offset < 0 || offset > inputlen) {
+               php_error_docref(NULL, E_WARNING, "Offset " ZEND_LONG_FMT " is out of input range" , offset);
+               RETURN_FALSE;
+       }
+       input += offset;
+       inputlen -= offset;
+
        array_init(return_value);
 
        while (formatlen-- > 0) {
index 1ef97ccbaf8299ce5617e048fe31a5edb01054cc..3a4f334c3b211b2510ab654a7f758499d4bdc939 100644 (file)
@@ -15,7 +15,7 @@ var_dump( unpack() );
 
 echo "\n-- Testing unpack() function with more than expected no. of arguments --\n";
 $extra_arg = 10;
-var_dump(unpack("I", pack("I", 65534), $extra_arg));
+var_dump(unpack("I", pack("I", 65534), 0, $extra_arg));
 
 echo "\n-- Testing unpack() function with invalid format character --\n";
 $extra_arg = 10;
@@ -27,12 +27,12 @@ var_dump(unpack("G", pack("I", 65534)));
 
 -- Testing unpack() function with no arguments --
 
-Warning: unpack() expects exactly 2 parameters, 0 given in %s on line %d
+Warning: unpack() expects at least 2 parameters, 0 given in %s on line %d
 NULL
 
 -- Testing unpack() function with more than expected no. of arguments --
 
-Warning: unpack() expects exactly 2 parameters, 3 given in %s on line %d
+Warning: unpack() expects at most 3 parameters, 4 given in %s on line %d
 NULL
 
 -- Testing unpack() function with invalid format character --
diff --git a/ext/standard/tests/strings/unpack_offset.phpt b/ext/standard/tests/strings/unpack_offset.phpt
new file mode 100644 (file)
index 0000000..c8c08e7
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+unpack() with offset
+--FILE--
+<?php
+$data = "pad" . pack("ll", 0x01020304, 0x05060708);
+
+$a = unpack("l2", $data, 3);
+printf("0x%08x 0x%08x\n", $a[1], $a[2]);
+
+printf("0x%08x 0x%08x\n",
+       unpack("l", $data, 3)[1],
+       unpack("@4/l", $data, 3)[1]);
+?>
+--EXPECT--
+0x01020304 0x05060708
+0x01020304 0x05060708
+