Skip to content

Commit a9a2610

Browse files
committed
unpack() function accepts an additional optional argument $offset.
1 parent de3e033 commit a9a2610

File tree

5 files changed

+35
-5
lines changed

5 files changed

+35
-5
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,6 @@ PHP NEWS
5353
(Ilia) (Julien)
5454
. Implemented FR #69359 (Provide a way to fetch the current environment
5555
variables). (Ferenc)
56+
. unpack() function accepts an additional optional argument $offset. (Dmitry)
5657

5758
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ PHP 7.1 UPGRADE NOTES
6363
pg_fetch_row().
6464
- pg_select() accepts 4th optional result type parameter like pg_fetch_row().
6565
- parse_url() is more restrictive now and supports RFC3986.
66+
- unpack() accepts an additional optional $offset argument. '@' format code
67+
(that specifes an absolute position) is applyed to input data after
68+
the $offset argument.
6669

6770
========================================
6871
6. New Functions

ext/standard/pack.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,9 +551,10 @@ PHP_FUNCTION(unpack)
551551
zend_string *formatarg, *inputarg;
552552
zend_long formatlen, inputpos, inputlen;
553553
int i;
554+
zend_long offset = 0;
554555

555-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &formatarg,
556-
&inputarg) == FAILURE) {
556+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &formatarg,
557+
&inputarg, &offset) == FAILURE) {
557558
return;
558559
}
559560

@@ -563,6 +564,14 @@ PHP_FUNCTION(unpack)
563564
inputlen = ZSTR_LEN(inputarg);
564565
inputpos = 0;
565566

567+
568+
if (offset < 0 || offset > inputlen) {
569+
php_error_docref(NULL, E_WARNING, "Offset " ZEND_LONG_FMT " is out of input range" , offset);
570+
RETURN_FALSE;
571+
}
572+
input += offset;
573+
inputlen -= offset;
574+
566575
array_init(return_value);
567576

568577
while (formatlen-- > 0) {

ext/standard/tests/strings/unpack_error.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var_dump( unpack() );
1515

1616
echo "\n-- Testing unpack() function with more than expected no. of arguments --\n";
1717
$extra_arg = 10;
18-
var_dump(unpack("I", pack("I", 65534), $extra_arg));
18+
var_dump(unpack("I", pack("I", 65534), 0, $extra_arg));
1919

2020
echo "\n-- Testing unpack() function with invalid format character --\n";
2121
$extra_arg = 10;
@@ -27,12 +27,12 @@ var_dump(unpack("G", pack("I", 65534)));
2727

2828
-- Testing unpack() function with no arguments --
2929

30-
Warning: unpack() expects exactly 2 parameters, 0 given in %s on line %d
30+
Warning: unpack() expects at least 2 parameters, 0 given in %s on line %d
3131
NULL
3232

3333
-- Testing unpack() function with more than expected no. of arguments --
3434

35-
Warning: unpack() expects exactly 2 parameters, 3 given in %s on line %d
35+
Warning: unpack() expects at most 3 parameters, 4 given in %s on line %d
3636
NULL
3737

3838
-- Testing unpack() function with invalid format character --
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
unpack() with offset
3+
--FILE--
4+
<?php
5+
$data = "pad" . pack("ll", 0x01020304, 0x05060708);
6+
7+
$a = unpack("l2", $data, 3);
8+
printf("0x%08x 0x%08x\n", $a[1], $a[2]);
9+
10+
printf("0x%08x 0x%08x\n",
11+
unpack("l", $data, 3)[1],
12+
unpack("@4/l", $data, 3)[1]);
13+
?>
14+
--EXPECT--
15+
0x01020304 0x05060708
16+
0x01020304 0x05060708
17+

0 commit comments

Comments
 (0)