diff options
author | Ilia Alshanetsky <iliaa@php.net> | 2006-11-19 18:20:48 +0000 |
---|---|---|
committer | Ilia Alshanetsky <iliaa@php.net> | 2006-11-19 18:20:48 +0000 |
commit | 0d338f463cc7f7980a1ac58809c14c005dd3e9ac (patch) | |
tree | ceed0ccf975a7ee0ebdc11198d0e7e1073bd78de | |
parent | c06f9e1efe5375abcbb507876e04e893885e4ade (diff) | |
download | php-git-0d338f463cc7f7980a1ac58809c14c005dd3e9ac.tar.gz |
Fixed bug #38770 (unpack() broken with longs on 64 bit machines).
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/standard/pack.c | 16 | ||||
-rw-r--r-- | ext/standard/tests/strings/bug38770.phpt | 25 |
3 files changed, 38 insertions, 5 deletions
@@ -74,6 +74,8 @@ PHP NEWS (Dmitry) - Fixed bug #39090 (DirectoryFilterDots doxygen docs and example is wrong). (Marcus) +- Fixed bug #38770 (unpack() broken with longs on 64 bit machines). (Ilia, + David Soria Parra). - Fixed bug #38698 (for some keys cdbmake creates corrupted db and cdb can't read valid db). (Marcus) - Fixed bug #38680 (Added missing handling of basic types in json_decode). diff --git a/ext/standard/pack.c b/ext/standard/pack.c index 85b2acda74..6a5bad826a 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -753,14 +753,16 @@ PHP_FUNCTION(unpack) case 'i': case 'I': { - long v; + long v = 0; int issigned = 0; if (type == 'i') { issigned = input[inputpos + (machine_little_endian ? (sizeof(int) - 1) : 0)] & 0x80; - } + } else if (sizeof(long) > 4 && (input[inputpos + machine_endian_long_map[3]] & 0x80) == 0x80) { + v = ~INT_MAX; + } - v = php_unpack(&input[inputpos], sizeof(int), issigned, int_map); + v |= php_unpack(&input[inputpos], sizeof(int), issigned, int_map); add_assoc_long(return_value, n, v); break; } @@ -771,7 +773,7 @@ PHP_FUNCTION(unpack) case 'V': { int issigned = 0; int *map = machine_endian_long_map; - long v; + long v = 0; if (type == 'l') { issigned = input[inputpos + (machine_little_endian ? 3 : 0)] & 0x80; @@ -781,7 +783,11 @@ PHP_FUNCTION(unpack) map = little_endian_long_map; } - v = php_unpack(&input[inputpos], 4, issigned, map); + if (sizeof(long) > 4 && (input[inputpos + machine_endian_long_map[3]] & 0x80) == 0x80) { + v = ~INT_MAX; + } + + v |= php_unpack(&input[inputpos], 4, issigned, map); add_assoc_long(return_value, n, v); break; } diff --git a/ext/standard/tests/strings/bug38770.phpt b/ext/standard/tests/strings/bug38770.phpt new file mode 100644 index 0000000000..2494a911bd --- /dev/null +++ b/ext/standard/tests/strings/bug38770.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #38770 (unpack() broken with longs on 64 bit machines) +--FILE-- +<?php + +foreach (array('N','I','l') as $v) { + print_r(unpack($v, pack($v, -30000))); +} + +echo "Done\n"; +?> +--EXPECT-- +Array +( + [1] => -30000 +) +Array +( + [1] => -30000 +) +Array +( + [1] => -30000 +) +Done |