diff --git a/ext/standard/pack.c b/ext/standard/pack.c index c2fa28f6dd5..3cd6ee7c503 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 10fcef83a7d..7130804fa41 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" -} -array(1) { - [1]=> - string(3) "foo" + 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(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 00000000000..59fc22e1222 --- /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 00000000000..8a2ee677676 --- /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" +}