From dbc5b42435a1d5c72d569814bd36e08fef5f028a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gustavo=20Andr=C3=A9=20dos=20Santos=20Lopes?= Date: Tue, 17 Apr 2012 22:18:48 +0100 Subject: [PATCH] pack() with new "Z" more in line with Perl. Made pack() with "Z" force NUL termination, even if it mean truncating input to less than the number of characters specified and if the number of characters is "*", the output will be one byte larger than the input. Improved tests. --- ext/standard/pack.c | 12 +++++++-- ext/standard/tests/strings/bug61038.phpt | 33 ++++++++---------------- ext/standard/tests/strings/pack_A.phpt | 25 ++++++++++++++++++ ext/standard/tests/strings/pack_Z.phpt | 27 +++++++++++++++++++ 4 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 ext/standard/tests/strings/pack_A.phpt create mode 100644 ext/standard/tests/strings/pack_Z.phpt diff --git a/ext/standard/pack.c b/ext/standard/pack.c index c2fa28f6dd..3cd6ee7c50 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -187,6 +187,12 @@ PHP_FUNCTION(pack) } convert_to_string_ex(argv[currentarg]); arg = Z_STRLEN_PP(argv[currentarg]); + if (code == 'Z') { + /* add one because Z is always NUL-terminated: + * pack("Z*", "aa") === "aa\0" + * pack("Z2", "aa") === "a\0" */ + arg++; + } } currentarg++; @@ -317,7 +323,8 @@ PHP_FUNCTION(pack) switch ((int) code) { case 'a': case 'A': - case 'Z': + case 'Z': { + int arg_cp = (code != 'Z') ? arg : MAX(0, arg - 1); memset(&output[outputpos], (code == 'a' || code == 'Z') ? '\0' : ' ', arg); val = argv[currentarg++]; if (Z_ISREF_PP(val)) { @@ -325,9 +332,10 @@ PHP_FUNCTION(pack) } convert_to_string_ex(val); memcpy(&output[outputpos], Z_STRVAL_PP(val), - (Z_STRLEN_PP(val) < arg) ? Z_STRLEN_PP(val) : arg); + (Z_STRLEN_PP(val) < arg_cp) ? Z_STRLEN_PP(val) : arg_cp); outputpos += arg; break; + } case 'h': case 'H': { diff --git a/ext/standard/tests/strings/bug61038.phpt b/ext/standard/tests/strings/bug61038.phpt index 10fcef83a7..7130804fa4 100644 --- a/ext/standard/tests/strings/bug61038.phpt +++ b/ext/standard/tests/strings/bug61038.phpt @@ -1,37 +1,26 @@ --TEST-- -BugFix #61038 +Bug #61038: unpack("a5", "str\0\0") does not work as expected --FILE-- --EXPECTF-- array(1) { [1]=> - string(3) "foo" + string(4) "str%c" } array(1) { [1]=> - string(4) "foo%c" -} -array(1) { - [1]=> - string(3) "foo" -} -array(1) { - [1]=> - string(9) "foo%cbar%c " -} -array(1) { - [1]=> - string(7) "foo%cbar" + string(5) "str%c%c" } + +Warning: unpack(): Type a: not enough input, need 6, have 5 in %s on line %d +bool(false) array(1) { [1]=> - string(3) "foo" + string(5) "str%c%c" } diff --git a/ext/standard/tests/strings/pack_A.phpt b/ext/standard/tests/strings/pack_A.phpt new file mode 100644 index 0000000000..59fc22e122 --- /dev/null +++ b/ext/standard/tests/strings/pack_A.phpt @@ -0,0 +1,25 @@ +--TEST-- +pack()/unpack(): "A" modifier +--FILE-- + +--EXPECTF-- +string(5) "foo " +string(4) "fooo" +string(4) "foo " +array(1) { + [1]=> + string(8) "foo%c%cbar" +} +array(1) { + [1]=> + string(3) "foo" +} + diff --git a/ext/standard/tests/strings/pack_Z.phpt b/ext/standard/tests/strings/pack_Z.phpt new file mode 100644 index 0000000000..8a2ee67767 --- /dev/null +++ b/ext/standard/tests/strings/pack_Z.phpt @@ -0,0 +1,27 @@ +--TEST-- +pack()/unpack(): "Z" format +--FILE-- + + string(3) "foo" +} +array(1) { + [1]=> + string(3) "foo" +} -- 2.50.1