Skip to content

Commit 7c03a10

Browse files
committed
Fix #79908: json_decode decodes negative zero as positive zero
While the JSON standard knows only numbers (i.e. it doesn't distinguish between int and float), and does not mention negative zero at all, PHP makes that distinction, so a negative zero should be parsed as such, even if the number is not otherwise designated as a float.
1 parent 9db3eda commit 7c03a10

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

ext/json/json_scanner.re

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@ std:
170170
return PHP_JSON_T_FALSE;
171171
}
172172
<JS>INT {
173-
zend_bool bigint = 0, negative = s->token[0] == '-';
173+
zend_bool bigint = 0, negative = s->token[0] == '-', neg_zero;
174174
size_t digits = (size_t) (s->cursor - s->token - negative);
175+
neg_zero = negative && digits == 1 && s->token[1] == '0';
175176
if (digits >= PHP_JSON_INT_MAX_LENGTH) {
176177
if (digits == PHP_JSON_INT_MAX_LENGTH) {
177178
int cmp = strncmp((char *) (s->token + negative), LONG_MIN_DIGITS, PHP_JSON_INT_MAX_LENGTH);
@@ -182,10 +183,10 @@ std:
182183
bigint = 1;
183184
}
184185
}
185-
if (!bigint) {
186+
if (EXPECTED(!neg_zero) && !bigint) {
186187
ZVAL_LONG(&s->value, ZEND_STRTOL((char *) s->token, NULL, 10));
187188
return PHP_JSON_T_INT;
188-
} else if (s->options & PHP_JSON_BIGINT_AS_STRING) {
189+
} else if (EXPECTED(!neg_zero) && s->options & PHP_JSON_BIGINT_AS_STRING) {
189190
ZVAL_STRINGL(&s->value, (char *) s->token, s->cursor - s->token);
190191
return PHP_JSON_T_STRING;
191192
} else {

ext/json/tests/bug79908.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #79908 (json_decode decodes negative zero as positive zero)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('json')) die("skip json extension not available");
6+
?>
7+
--FILE--
8+
<?php
9+
var_dump(json_decode("-0"));
10+
?>
11+
--EXPECT--
12+
float(-0)

0 commit comments

Comments
 (0)