diff --git a/phongo_compat.h b/phongo_compat.h index edd7bf234..af175a4b3 100644 --- a/phongo_compat.h +++ b/phongo_compat.h @@ -143,22 +143,22 @@ # define ADD_ASSOC_INT64(zval, key, value) add_assoc_long(zval, key, value) #elif SIZEOF_PHONGO_LONG == 4 # define ADD_INDEX_INT64(zval, index, value) \ - if (value > INT32_MAX || value < INT32_MIN) { \ - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", value); \ + if ((value) > INT32_MAX || (value) < INT32_MIN) { \ + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", (value)); \ } else { \ - add_index_long(zval, index, value); \ + add_index_long(zval, index, (value)); \ } # define ADD_NEXT_INDEX_INT64(zval, value) \ - if (value > INT32_MAX || value < INT32_MIN) { \ - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", value); \ + if ((value) > INT32_MAX || (value) < INT32_MIN) { \ + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", (value)); \ } else { \ - add_next_index_long(zval, value); \ + add_next_index_long(zval, (value)); \ } # define ADD_ASSOC_INT64(zval, key, value) \ - if (value > INT32_MAX || value < INT32_MIN) { \ - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", value); \ + if ((value) > INT32_MAX || (value) < INT32_MIN) { \ + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", (value)); \ } else { \ - add_assoc_long(zval, key, value); \ + add_assoc_long(zval, key, (value)); \ } #else # error Unsupported architecture (integers are neither 32-bit nor 64-bit) diff --git a/php_phongo.c b/php_phongo.c index 7c89f8ae3..b959504e4 100644 --- a/php_phongo.c +++ b/php_phongo.c @@ -230,7 +230,7 @@ static void php_phongo_log(mongoc_log_level_t log_level, const char *log_domain, dt = php_format_date((char *) ZEND_STRL("Y-m-d\\TH:i:s"), t, 0 TSRMLS_CC); - fprintf(MONGODB_G(debug_fd), "[%s.%06lu+00:00] %10s: %-8s> %s\n", ZSTR_VAL(dt), tu, log_domain, mongoc_log_level_str(log_level), message); + fprintf(MONGODB_G(debug_fd), "[%s.%06" PHONGO_LONG_FORMAT "+00:00] %10s: %-8s> %s\n", ZSTR_VAL(dt), tu, log_domain, mongoc_log_level_str(log_level), message); fflush(MONGODB_G(debug_fd)); efree(dt); } diff --git a/scripts/convert-bson-corpus-tests.php b/scripts/convert-bson-corpus-tests.php index 67b773611..d33b98433 100644 --- a/scripts/convert-bson-corpus-tests.php +++ b/scripts/convert-bson-corpus-tests.php @@ -14,6 +14,11 @@ 'Top-level document validity: Bad $date (number, not string or hash)' => 'Legacy extended JSON $date syntax uses numbers (CDRIVER-2223)', ]; +$for64bitOnly = [ + 'Int64 type: MinValue' => "Can't represent 64-bit ints on a 32-bit platform", + 'Int64 type: MaxValue' => "Can't represent 64-bit ints on a 32-bit platform", +]; + $outputPath = realpath(__DIR__ . '/../tests') . '/bson-corpus/'; if ( ! is_dir($outputPath) && ! mkdir($outputPath, 0755, true)) { @@ -42,7 +47,7 @@ foreach ($test['valid'] as $i => $case) { $outputFile = sprintf('%s-valid-%03d.phpt', pathinfo($inputFile, PATHINFO_FILENAME), $i + 1); try { - $output = renderPhpt(getParamsForValid($test, $case), $expectedFailures); + $output = renderPhpt(getParamsForValid($test, $case), $expectedFailures, $for64bitOnly); } catch (Exception $e) { printf("Error processing valid[%d] in %s: %s\n", $i, $inputFile, $e->getMessage()); continue; @@ -59,7 +64,7 @@ foreach ($test['decodeErrors'] as $i => $case) { $outputFile = sprintf('%s-decodeError-%03d.phpt', pathinfo($inputFile, PATHINFO_FILENAME), $i + 1); try { - $output = renderPhpt(getParamsForDecodeError($test, $case), $expectedFailures); + $output = renderPhpt(getParamsForDecodeError($test, $case), $expectedFailures, $for64bitOnly); } catch (Exception $e) { printf("Error processing decodeErrors[%d] in %s: %s\n", $i, $inputFile, $e->getMessage()); continue; @@ -76,7 +81,7 @@ foreach ($test['parseErrors'] as $i => $case) { $outputFile = sprintf('%s-parseError-%03d.phpt', pathinfo($inputFile, PATHINFO_FILENAME), $i + 1); try { - $output = renderPhpt(getParamsForParseError($test, $case), $expectedFailures); + $output = renderPhpt(getParamsForParseError($test, $case), $expectedFailures, $for64bitOnly); } catch (Exception $e) { printf("Error processing parseErrors[%d] in %s: %s\n", $i, $inputFile, $e->getMessage()); continue; @@ -263,16 +268,19 @@ function getParamsForParseError(array $test, array $case) ]; } -function renderPhpt(array $params, array $expectedFailures) +function renderPhpt(array $params, array $expectedFailures, array $for64bitOnly) { $params['%XFAIL%'] = isset($expectedFailures[$params['%NAME%']]) ? "--XFAIL--\n" . $expectedFailures[$params['%NAME%']] . "\n" : ''; + $params['%SKIPIF%'] = isset($for64bitOnly[$params['%NAME%']]) + ? "--SKIPIF--\n" . "" . "\n" + : ''; $template = <<< 'TEMPLATE' --TEST-- %NAME% -%XFAIL%--DESCRIPTION-- +%XFAIL%%SKIPIF%--DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE diff --git a/src/MongoDB/Monitoring/CommandFailedEvent.c b/src/MongoDB/Monitoring/CommandFailedEvent.c index a336d49f5..c79abd6a8 100644 --- a/src/MongoDB/Monitoring/CommandFailedEvent.c +++ b/src/MongoDB/Monitoring/CommandFailedEvent.c @@ -214,7 +214,7 @@ static HashTable *php_phongo_commandfailedevent_get_debug_info(zval *object, int array_init_size(&retval, 6); ADD_ASSOC_STRING(&retval, "commandName", intern->command_name); - ADD_ASSOC_INT64(&retval, "durationMicros", intern->duration_micros); + ADD_ASSOC_INT64(&retval, "durationMicros", (int64_t) intern->duration_micros); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "error", &intern->z_error); diff --git a/src/MongoDB/Monitoring/CommandSucceededEvent.c b/src/MongoDB/Monitoring/CommandSucceededEvent.c index b1a4c5fdf..fe6d0d4d0 100644 --- a/src/MongoDB/Monitoring/CommandSucceededEvent.c +++ b/src/MongoDB/Monitoring/CommandSucceededEvent.c @@ -216,7 +216,7 @@ static HashTable *php_phongo_commandsucceededevent_get_debug_info(zval *object, array_init_size(&retval, 6); ADD_ASSOC_STRING(&retval, "commandName", intern->command_name); - ADD_ASSOC_INT64(&retval, "durationMicros", intern->duration_micros); + ADD_ASSOC_INT64(&retval, "durationMicros", (int64_t) intern->duration_micros); sprintf(operation_id, "%" PHONGO_LONG_FORMAT, intern->operation_id); ADD_ASSOC_STRING(&retval, "operationId", operation_id); diff --git a/tests/bson-corpus/int64-valid-001.phpt b/tests/bson-corpus/int64-valid-001.phpt index cae95fa9a..4f63a6d7a 100644 --- a/tests/bson-corpus/int64-valid-001.phpt +++ b/tests/bson-corpus/int64-valid-001.phpt @@ -1,5 +1,7 @@ --TEST-- Int64 type: MinValue +--SKIPIF-- + --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php diff --git a/tests/bson-corpus/int64-valid-002.phpt b/tests/bson-corpus/int64-valid-002.phpt index 7d4468a36..394af40b0 100644 --- a/tests/bson-corpus/int64-valid-002.phpt +++ b/tests/bson-corpus/int64-valid-002.phpt @@ -1,5 +1,7 @@ --TEST-- Int64 type: MaxValue +--SKIPIF-- + --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php diff --git a/tests/bson/bson-timestamp_error-003.phpt b/tests/bson/bson-timestamp_error-003.phpt index 459ad0977..3e91b5f2b 100644 --- a/tests/bson/bson-timestamp_error-003.phpt +++ b/tests/bson/bson-timestamp_error-003.phpt @@ -10,7 +10,10 @@ echo throws(function() { }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { - new MongoDB\BSON\Timestamp(-2147483648, 0); + /* I realise that "-2147483647 - 1" could be written as "-2147483648", *however*, PHP considers + * the latter a floating point number, as it parses "-" and "2147483648" separately, and + * "2147483648" doesn't fit in the 32-bit signed range. */ + new MongoDB\BSON\Timestamp(-2147483647 - 1, 0); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { @@ -18,7 +21,7 @@ echo throws(function() { }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { - new MongoDB\BSON\Timestamp(0, -2147483648); + new MongoDB\BSON\Timestamp(0, -2147483647 - 1); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> diff --git a/tests/causal-consistency/causal-consistency-011.phpt b/tests/causal-consistency/causal-consistency-011.phpt index 568e686a7..ef4b79231 100644 --- a/tests/causal-consistency/causal-consistency-011.phpt +++ b/tests/causal-consistency/causal-consistency-011.phpt @@ -1,9 +1,8 @@ --TEST-- Causal consistency: $clusterTime is not sent in commands to unsupported deployments --SKIPIF-- - - + --FILE-- --FILE-- diff --git a/tests/manager/manager-executeBulkWrite-008.phpt b/tests/manager/manager-executeBulkWrite-008.phpt index d4aed4d05..f7e6c1b99 100644 --- a/tests/manager/manager-executeBulkWrite-008.phpt +++ b/tests/manager/manager-executeBulkWrite-008.phpt @@ -1,7 +1,6 @@ --TEST-- MongoDB\Driver\Manager::executeBulkWrite() update multiple documents with no upsert --SKIPIF-- - --FILE-- diff --git a/tests/manager/manager-executeCommand-004.phpt b/tests/manager/manager-executeCommand-004.phpt index 5bafd9f80..bfb1f3b8c 100644 --- a/tests/manager/manager-executeCommand-004.phpt +++ b/tests/manager/manager-executeCommand-004.phpt @@ -1,9 +1,8 @@ --TEST-- MongoDB\Driver\Manager::executeCommand() options (MONGOC_CMD_RAW) --SKIPIF-- - - + --FILE-- - + --FILE-- - + --FILE-- - + --FILE-- - + --FILE-- - + --FILE-- - + --FILE-- - + --FILE-- - + --FILE-- - + --FILE-- - + --FILE-- 1]); + $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY); + + try { + $cursor = $manager->executeCommand("admin", $cmd, $rp); + $cursor->setTypeMap(['root' => 'array', 'document' => 'array']); + $document = current($cursor->toArray()); + + if (version_compare($document['version'], $version, '<')) { + echo "skip Needs version >= $version, but is {$document['version']}"; + } + } catch(Exception $e) { + echo "skip (needs version); $uri ($version): " . $e->getCode(), ": ", $e->getMessage(); + exit(1); + } +} + +function NEEDS_STORAGE_ENGINE($uri, $engine) { + $manager = new MongoDB\Driver\Manager($uri); + $cmd = new MongoDB\Driver\Command(["serverStatus" => 1]); + $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY); + + try { + $cursor = $manager->executeCommand("admin", $cmd, $rp); + $cursor->setTypeMap(['root' => 'array', 'document' => 'array']); + $document = current($cursor->toArray()); + + if ($document['storageEngine']['name'] != $engine) { + echo "skip Needs storage engine '$engine', but is '{$document['storageEngine']['name']}'"; + } + } catch(Exception $e) { + echo "skip (needs version); $uri ($version): " . $e->getCode(), ": ", $e->getMessage(); + exit(1); + } +} + function CLEANUP($uri, $dbname = DATABASE_NAME, $collname = COLLECTION_NAME) { try { $manager = new MongoDB\Driver\Manager($uri);