Skip to content

Commit 87c53a8

Browse files
committed
Merge pull request #241
2 parents e430814 + dcd4a6d commit 87c53a8

File tree

5 files changed

+252
-54
lines changed

5 files changed

+252
-54
lines changed

phongo_compat.h

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -92,34 +92,6 @@
9292
# define ARG_UNUSED
9393
#endif
9494

95-
#if SIZEOF_LONG == 4
96-
# define ADD_INDEX_INT64(zval, index, value) \
97-
if (value > LONG_MAX || value < LONG_MIN) { \
98-
char *tmp; \
99-
int tmp_len; \
100-
mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Integer overflow detected on your platform: %lld", value); \
101-
tmp_len = spprintf(&tmp, 0, "%lld", value); \
102-
ADD_INDEX_STRINGL(zval, index, tmp, tmp_len); \
103-
efree(tmp); \
104-
} else { \
105-
add_index_long(zval, index, val); \
106-
}
107-
# define ADD_ASSOC_INT64(zval, key, value) \
108-
if (value > LONG_MAX || value < LONG_MIN) { \
109-
char *tmp; \
110-
int tmp_len; \
111-
mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Integer overflow detected on your platform: %lld", value); \
112-
tmp_len = spprintf(&tmp, 0, "%lld", value); \
113-
ADD_ASSOC_STRINGL(zval, key, tmp, tmp_len); \
114-
efree(tmp); \
115-
} else { \
116-
add_assoc_long(zval, key, value); \
117-
}
118-
#else
119-
# define ADD_INDEX_INT64(zval, index, value) add_index_long(zval, index, value)
120-
# define ADD_ASSOC_INT64(zval, key, value) add_assoc_long(zval, key, value);
121-
#endif
122-
12395
#ifdef HAVE_ATOLL
12496
# define STRTOLL(s) atoll(s)
12597
#else
@@ -151,6 +123,8 @@
151123
# define phongo_char zend_string
152124
# define phongo_char_pdup(str) pestrdup(filename->val, 1)
153125
# define phongo_char_free(str) zend_string_release(str)
126+
# define phongo_long zend_long
127+
# define SIZEOF_PHONGO_LONG SIZEOF_ZEND_LONG
154128
# define phongo_str(str) str->val
155129
# define phongo_create_object_retval zend_object*
156130
# define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t *)ecalloc(1, sizeof(_obj_t)+zend_object_properties_size(_class_type))
@@ -178,6 +152,8 @@
178152
# define phongo_char char
179153
# define phongo_char_pdup(str) pestrdup(filename, 1)
180154
# define phongo_char_free(str) _efree(str ZEND_FILE_LINE_CC ZEND_FILE_LINE_CC)
155+
# define phongo_long long
156+
# define SIZEOF_PHONGO_LONG SIZEOF_LONG
181157
# define phongo_str(str) str
182158
# define phongo_create_object_retval zend_object_value
183159
# define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t *)ecalloc(1, sizeof(_obj_t))
@@ -206,6 +182,35 @@
206182
# define PHP_STREAM_CONTEXT(stream) ((php_stream_context*) (stream)->context)
207183
#endif
208184

185+
#if SIZEOF_PHONGO_LONG == 8
186+
# define ADD_INDEX_INT64(zval, index, value) add_index_long(zval, index, value)
187+
# define ADD_ASSOC_INT64(zval, key, value) add_assoc_long(zval, key, value)
188+
#elif SIZEOF_PHONGO_LONG == 4
189+
# define ADD_INDEX_INT64(zval, index, value) \
190+
if (value > INT32_MAX || value < INT32_MIN) { \
191+
char *tmp; \
192+
int tmp_len; \
193+
mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Integer overflow detected on your platform: %lld", value); \
194+
tmp_len = spprintf(&tmp, 0, "%lld", value); \
195+
ADD_INDEX_STRINGL(zval, index, tmp, tmp_len); \
196+
efree(tmp); \
197+
} else { \
198+
add_index_long(zval, index, val); \
199+
}
200+
# define ADD_ASSOC_INT64(zval, key, value) \
201+
if (value > INT32_MAX || value < INT32_MIN) { \
202+
char *tmp; \
203+
int tmp_len; \
204+
mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Integer overflow detected on your platform: %lld", value); \
205+
tmp_len = spprintf(&tmp, 0, "%lld", value); \
206+
ADD_ASSOC_STRING_EX(zval, key, strlen(key), tmp, tmp_len); \
207+
efree(tmp); \
208+
} else { \
209+
add_assoc_long(zval, key, value); \
210+
}
211+
#else
212+
# error Unsupported architecture (integers are neither 32-bit nor 64-bit)
213+
#endif
209214

210215
void *x509_from_zval(zval *zval TSRMLS_DC);
211216
void phongo_add_exception_prop(const char *prop, int prop_len, zval *value TSRMLS_DC);

src/BSON/UTCDateTime.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,30 +52,36 @@ PHP_METHOD(UTCDateTime, __construct)
5252
{
5353
php_phongo_utcdatetime_t *intern;
5454
zend_error_handling error_handling;
55-
long milliseconds;
56-
#if SIZEOF_LONG == 4
57-
char *s_milliseconds;
58-
int s_milliseconds_len;
59-
#endif
6055

6156

6257
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
6358
intern = Z_UTCDATETIME_OBJ_P(getThis());
6459

65-
#if SIZEOF_LONG == 4
66-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s_milliseconds, &s_milliseconds_len) == FAILURE) {
67-
zend_restore_error_handling(&error_handling TSRMLS_CC);
68-
return;
69-
}
60+
#if SIZEOF_PHONGO_LONG == 8
61+
{
62+
phongo_long milliseconds;
7063

71-
intern->milliseconds = STRTOLL(s_milliseconds);
72-
#else
73-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &milliseconds) == FAILURE) {
74-
zend_restore_error_handling(&error_handling TSRMLS_CC);
75-
return;
64+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &milliseconds) == FAILURE) {
65+
zend_restore_error_handling(&error_handling TSRMLS_CC);
66+
return;
67+
}
68+
69+
intern->milliseconds = milliseconds;
7670
}
71+
#elif SIZEOF_PHONGO_LONG == 4
72+
{
73+
char *s_milliseconds;
74+
phongo_zpp_char_len s_milliseconds_len;
7775

78-
intern->milliseconds = milliseconds;
76+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s_milliseconds, &s_milliseconds_len) == FAILURE) {
77+
zend_restore_error_handling(&error_handling TSRMLS_CC);
78+
return;
79+
}
80+
81+
intern->milliseconds = STRTOLL(s_milliseconds);
82+
}
83+
#else
84+
# error Unsupported architecture (integers are neither 32-bit nor 64-bit)
7985
#endif
8086

8187
zend_restore_error_handling(&error_handling TSRMLS_CC);

src/bson.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,18 @@
4141
#include "php_phongo.h"
4242
#include "php_bson.h"
4343

44-
45-
#define BSON_APPEND_INT32(b,key,val) \
46-
bson_append_int32 (b, key, (int) strlen (key), val)
47-
48-
#if SIZEOF_LONG == 8
49-
# define BSON_APPEND_INT(b, key, keylen, val) \
50-
if (val > INT_MAX || val < INT_MIN) { \
44+
#if SIZEOF_PHONGO_LONG == 8
45+
# define BSON_APPEND_INT(b, key, keylen, val) \
46+
if (val > INT32_MAX || val < INT32_MIN) { \
5147
bson_append_int64(b, key, keylen, val); \
5248
} else { \
5349
bson_append_int32(b, key, keylen, val); \
5450
}
55-
#elif SIZEOF_LONG == 4
56-
# define BSON_APPEND_INT(b, key, keylen, val) \
57-
bson_append_int32(b, key, keylen, val);
51+
#elif SIZEOF_PHONGO_LONG == 4
52+
# define BSON_APPEND_INT(b, key, keylen, val) \
53+
bson_append_int32(b, key, keylen, val)
54+
#else
55+
# error Unsupported architecture (integers are neither 32-bit nor 64-bit)
5856
#endif
5957

6058
#undef MONGOC_LOG_DOMAIN

tests/bson/bug0544.phpt

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
--TEST--
2+
PHPC-544: Consult SIZEOF_ZEND_LONG for 64-bit integer support
3+
--SKIPIF--
4+
<?php if (8 !== PHP_INT_SIZE) { die('skip Only for 64-bit platform'); } ?>
5+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
6+
--INI--
7+
mongodb.debug=stderr
8+
--FILE--
9+
<?php
10+
11+
require_once __DIR__ . "/../utils/basic.inc";
12+
13+
$tests = [
14+
['x' => -2147483648],
15+
['x' => 2147483647],
16+
['x' => -4294967294],
17+
['x' => 4294967294],
18+
['x' => -4294967295],
19+
['x' => 4294967295],
20+
['x' => -9223372036854775807],
21+
['x' => 9223372036854775807],
22+
];
23+
24+
foreach ($tests as $test) {
25+
$bson = fromPHP($test);
26+
/* Note: Although libbson can parse the extended JSON representation for
27+
* 64-bit integers (i.e. "$numberLong"), it currently prints them as
28+
* doubles (see: https://jira.mongodb.org/browse/CDRIVER-375). */
29+
printf("Test %s\n", toJSON($bson));
30+
hex_dump($bson);
31+
var_dump(toPHP($bson));
32+
echo "\n";
33+
}
34+
35+
?>
36+
===DONE===
37+
<?php exit(0); ?>
38+
--EXPECTF--
39+
Test { "x" : -2147483648 }
40+
0 : 0c 00 00 00 10 78 00 00 00 00 80 00 [.....x......]
41+
object(stdClass)#%d (%d) {
42+
["x"]=>
43+
int(-2147483648)
44+
}
45+
46+
Test { "x" : 2147483647 }
47+
0 : 0c 00 00 00 10 78 00 ff ff ff 7f 00 [.....x......]
48+
object(stdClass)#%d (%d) {
49+
["x"]=>
50+
int(2147483647)
51+
}
52+
53+
Test { "x" : -4294967294 }
54+
0 : 10 00 00 00 12 78 00 02 00 00 00 ff ff ff ff 00 [.....x..........]
55+
object(stdClass)#%d (%d) {
56+
["x"]=>
57+
int(-4294967294)
58+
}
59+
60+
Test { "x" : 4294967294 }
61+
0 : 10 00 00 00 12 78 00 fe ff ff ff 00 00 00 00 00 [.....x..........]
62+
object(stdClass)#%d (%d) {
63+
["x"]=>
64+
int(4294967294)
65+
}
66+
67+
Test { "x" : -4294967295 }
68+
0 : 10 00 00 00 12 78 00 01 00 00 00 ff ff ff ff 00 [.....x..........]
69+
object(stdClass)#%d (%d) {
70+
["x"]=>
71+
int(-4294967295)
72+
}
73+
74+
Test { "x" : 4294967295 }
75+
0 : 10 00 00 00 12 78 00 ff ff ff ff 00 00 00 00 00 [.....x..........]
76+
object(stdClass)#%d (%d) {
77+
["x"]=>
78+
int(4294967295)
79+
}
80+
81+
Test { "x" : -9223372036854775807 }
82+
0 : 10 00 00 00 12 78 00 01 00 00 00 00 00 00 80 00 [.....x..........]
83+
object(stdClass)#%d (%d) {
84+
["x"]=>
85+
int(-9223372036854775807)
86+
}
87+
88+
Test { "x" : 9223372036854775807 }
89+
0 : 10 00 00 00 12 78 00 ff ff ff ff ff ff ff 7f 00 [.....x..........]
90+
object(stdClass)#%d (%d) {
91+
["x"]=>
92+
int(9223372036854775807)
93+
}
94+
95+
===DONE===

tests/bson/bug0592.phpt

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
--TEST--
2+
PHPC-592: Property name corrupted when unserializing 64-bit integer on 32-bit platform
3+
--SKIPIF--
4+
<?php if (4 !== PHP_INT_SIZE) { die('skip Only for 32-bit platform'); } ?>
5+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
6+
--INI--
7+
mongodb.debug=stderr
8+
--FILE--
9+
<?php
10+
11+
require_once __DIR__ . "/../utils/basic.inc";
12+
13+
$tests = [
14+
'{ "x": { "$numberLong": "-2147483648" }}',
15+
'{ "x": { "$numberLong": "2147483647" }}',
16+
'{ "x": { "$numberLong": "4294967294" }}',
17+
'{ "x": { "$numberLong": "4294967295" }}',
18+
'{ "x": { "$numberLong": "9223372036854775807" }}',
19+
'{ "longFieldName": { "$numberLong": "-2147483648" }}',
20+
'{ "longFieldName": { "$numberLong": "2147483647" }}',
21+
'{ "longFieldName": { "$numberLong": "4294967294" }}',
22+
'{ "longFieldName": { "$numberLong": "4294967295" }}',
23+
'{ "longFieldName": { "$numberLong": "9223372036854775807" }}',
24+
];
25+
26+
foreach ($tests as $json) {
27+
printf("Test %s\n", $json);
28+
var_dump(toPHP(fromJSON($json)));
29+
echo "\n";
30+
}
31+
32+
?>
33+
===DONE===
34+
<?php exit(0); ?>
35+
--EXPECTF--
36+
Test { "x": { "$numberLong": "-2147483648" }}
37+
object(stdClass)#%d (%d) {
38+
["x"]=>
39+
int(-2147483648)
40+
}
41+
42+
Test { "x": { "$numberLong": "2147483647" }}
43+
object(stdClass)#%d (%d) {
44+
["x"]=>
45+
int(2147483647)
46+
}
47+
48+
Test { "x": { "$numberLong": "4294967295" }}
49+
[%s] PHONGO-BSON: WARNING > ENTRY: Integer overflow detected on your platform: 4294967295
50+
object(stdClass)#%d (%d) {
51+
["x"]=>
52+
string(10) "4294967295"
53+
}
54+
55+
Test { "x": { "$numberLong": "9223372036854775807" }}
56+
[%s] PHONGO-BSON: WARNING > ENTRY: Integer overflow detected on your platform: 9223372036854775807
57+
object(stdClass)#%d (%d) {
58+
["x"]=>
59+
string(19) "9223372036854775807"
60+
}
61+
62+
Test { "longFieldName": { "$numberLong": "-2147483648" }}
63+
object(stdClass)#%d (%d) {
64+
["longFieldName"]=>
65+
int(-2147483648)
66+
}
67+
68+
Test { "longFieldName": { "$numberLong": "2147483647" }}
69+
object(stdClass)#%d (%d) {
70+
["longFieldName"]=>
71+
int(2147483647)
72+
}
73+
74+
Test { "longFieldName": { "$numberLong": "4294967294" }}
75+
object(stdClass)#%d (%d) {
76+
["longFieldName"]=>
77+
string(10) "4294967294"
78+
}
79+
80+
Test { "longFieldName": { "$numberLong": "4294967295" }}
81+
[%s] PHONGO-BSON: WARNING > ENTRY: Integer overflow detected on your platform: 4294967295
82+
object(stdClass)#%d (%d) {
83+
["longFieldName"]=>
84+
string(10) "4294967295"
85+
}
86+
87+
Test { "longFieldName": { "$numberLong": "9223372036854775807" }}
88+
[%s] PHONGO-BSON: WARNING > ENTRY: Integer overflow detected on your platform: 9223372036854775807
89+
object(stdClass)#%d (%d) {
90+
["longFieldName"]=>
91+
string(19) "9223372036854775807"
92+
}
93+
94+
===DONE===

0 commit comments

Comments
 (0)