diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | UPGRADING | 3 | ||||
-rw-r--r-- | ext/standard/pack.c | 13 | ||||
-rw-r--r-- | ext/standard/tests/strings/unpack_error.phpt | 6 | ||||
-rw-r--r-- | ext/standard/tests/strings/unpack_offset.phpt | 17 |
5 files changed, 35 insertions, 5 deletions
@@ -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! >>> @@ -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 diff --git a/ext/standard/pack.c b/ext/standard/pack.c index a24ee69ad2..1d353d1743 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -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) { diff --git a/ext/standard/tests/strings/unpack_error.phpt b/ext/standard/tests/strings/unpack_error.phpt index 1ef97ccbaf..3a4f334c3b 100644 --- a/ext/standard/tests/strings/unpack_error.phpt +++ b/ext/standard/tests/strings/unpack_error.phpt @@ -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 index 0000000000..c8c08e74f2 --- /dev/null +++ b/ext/standard/tests/strings/unpack_offset.phpt @@ -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 + |