summaryrefslogtreecommitdiff
path: root/ext/json
diff options
context:
space:
mode:
authorMatt Wilmas <mattwil@php.net>2009-03-19 19:26:00 +0000
committerMatt Wilmas <mattwil@php.net>2009-03-19 19:26:00 +0000
commit91d325dd729391b74d1cf5410778a27bbba84041 (patch)
tree33feb0128fd2f8d280eb1bcb52980efa32e0ae02 /ext/json
parent021e5d168fe3e13e50f91a3e5523ad8ae86be054 (diff)
downloadphp-git-91d325dd729391b74d1cf5410778a27bbba84041.tar.gz
MFH: Avoid 2 conversions when decoding numbers
Diffstat (limited to 'ext/json')
-rw-r--r--ext/json/JSON_parser.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/ext/json/JSON_parser.c b/ext/json/JSON_parser.c
index 7125012610..6aae849f16 100644
--- a/ext/json/JSON_parser.c
+++ b/ext/json/JSON_parser.c
@@ -289,16 +289,27 @@ static void json_create_zval(zval **z, smart_str *buf, int type)
if (type == IS_LONG)
{
- long l = strtol(buf->c, NULL, 10);
- double d = zend_strtod(buf->c, NULL);
- if (d > LONG_MAX || d < LONG_MIN) {
- ZVAL_DOUBLE(*z, d);
- } else {
- ZVAL_LONG(*z, l);
+ if (buf->c[0] == '-') {
+ buf->len--;
+ }
+
+ if (buf->len >= MAX_LENGTH_OF_LONG - 1) {
+ if (buf->len == MAX_LENGTH_OF_LONG - 1) {
+ int cmp = strcmp(buf->c + (buf->c[0] == '-'), long_min_digits);
+
+ if (!(cmp < 0 || (cmp == 0 && buf->c[0] == '-'))) {
+ goto use_double;
+ }
+ } else {
+ goto use_double;
+ }
}
+
+ ZVAL_LONG(*z, strtol(buf->c, NULL, 10));
}
else if (type == IS_DOUBLE)
{
+use_double:
ZVAL_DOUBLE(*z, zend_strtod(buf->c, NULL));
}
else if (type == IS_STRING)