From: Gustavo André dos Santos Lopes Date: Tue, 17 Apr 2012 21:18:48 +0000 (+0100) Subject: pack() with new "Z" more in line with Perl. X-Git-Tag: php-5.5.0alpha1~296 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dbc5b42435a1d5c72d569814bd36e08fef5f028a;p=php 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. --- 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" +}