Skip to content

Merge v1.x into v2.x #1786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 67 additions & 50 deletions src/BSON/Document.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,36 @@ static bool php_phongo_document_get(php_phongo_document_t* intern, char* key, si
return true;
}

static bool php_phongo_document_get_by_zval(php_phongo_document_t* intern, zval* key, zval* return_value, bool null_if_missing)
{
if (Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_LONG) {
if (null_if_missing) {
ZVAL_NULL(return_value);
return true;
}

phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Could not find key of type \"%s\" in BSON document", zend_zval_type_name(key));
return false;
}

zend_string* tmp_str;
zend_string* str = zval_try_get_tmp_string(key, &tmp_str);

if (!str) {
// Exception already thrown
return false;
}

if (!php_phongo_document_get(intern, ZSTR_VAL(str), ZSTR_LEN(str), return_value, null_if_missing)) {
// Exception already thrown
zend_tmp_string_release(tmp_str);
return false;
}

zend_tmp_string_release(tmp_str);
return true;
}

static PHP_METHOD(MongoDB_BSON_Document, get)
{
php_phongo_document_t* intern;
Expand All @@ -204,10 +234,8 @@ static PHP_METHOD(MongoDB_BSON_Document, get)

intern = Z_DOCUMENT_OBJ_P(getThis());

if (!php_phongo_document_get(intern, key, key_len, return_value, false)) {
// Exception already thrown
RETURN_NULL();
}
// May throw, in which case we do nothing
php_phongo_document_get(intern, key, key_len, return_value, false);
}

static PHP_METHOD(MongoDB_BSON_Document, getIterator)
Expand All @@ -229,6 +257,30 @@ static bool php_phongo_document_has(php_phongo_document_t* intern, char* key, si
return bson_iter_find_w_len(&iter, key, key_len);
}

static bool php_phongo_document_has_by_zval(php_phongo_document_t* intern, zval* key)
{
if (Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_LONG) {
return false;
}

zend_string* tmp_str;
zend_string* str = zval_try_get_tmp_string(key, &tmp_str);

if (!str) {
// Exception already thrown
return false;
}

if (!php_phongo_document_has(intern, ZSTR_VAL(str), ZSTR_LEN(str))) {
// Exception may be thrown if BSON iterator could not be initialized
zend_tmp_string_release(tmp_str);
return false;
}

zend_tmp_string_release(tmp_str);
return true;
}

static PHP_METHOD(MongoDB_BSON_Document, has)
{
php_phongo_document_t* intern;
Expand Down Expand Up @@ -309,11 +361,7 @@ static PHP_METHOD(MongoDB_BSON_Document, offsetExists)

intern = Z_DOCUMENT_OBJ_P(getThis());

if (Z_TYPE_P(offset) != IS_STRING) {
RETURN_FALSE;
}

RETURN_BOOL(php_phongo_document_has(intern, Z_STRVAL_P(offset), Z_STRLEN_P(offset)));
RETURN_BOOL(php_phongo_document_has_by_zval(intern, offset));
}

static PHP_METHOD(MongoDB_BSON_Document, offsetGet)
Expand All @@ -327,13 +375,8 @@ static PHP_METHOD(MongoDB_BSON_Document, offsetGet)

intern = Z_DOCUMENT_OBJ_P(getThis());

if (Z_TYPE_P(offset) != IS_STRING) {
phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Could not find key of type \"%s\" in BSON document", zend_zval_type_name(offset));
return;
}

// May throw, in which case we do nothing
php_phongo_document_get(intern, Z_STRVAL_P(offset), Z_STRLEN_P(offset), return_value, false);
php_phongo_document_get_by_zval(intern, offset, return_value, false);
}

static PHP_METHOD(MongoDB_BSON_Document, offsetSet)
Expand Down Expand Up @@ -550,13 +593,9 @@ static HashTable* php_phongo_document_get_properties(zend_object* object)

zval* php_phongo_document_read_property(zend_object* object, zend_string* member, int type, void** cache_slot, zval* rv)
{
php_phongo_document_t* intern;
char* key = ZSTR_VAL(member);
size_t key_len = ZSTR_LEN(member);

intern = Z_OBJ_DOCUMENT(object);
php_phongo_document_t* intern = Z_OBJ_DOCUMENT(object);

if (!php_phongo_document_get(intern, key, key_len, rv, type == BP_VAR_IS)) {
if (!php_phongo_document_get(intern, ZSTR_VAL(member), ZSTR_LEN(member), rv, type == BP_VAR_IS)) {
// Exception already thrown
return &EG(uninitialized_zval);
}
Expand All @@ -570,15 +609,11 @@ zval* php_phongo_document_write_property(zend_object* object, zend_string* membe
return value;
}

int php_phongo_document_has_property(zend_object* object, zend_string* name, int has_set_exists, void** cache_slot)
int php_phongo_document_has_property(zend_object* object, zend_string* member, int has_set_exists, void** cache_slot)
{
php_phongo_document_t* intern;
char* key = ZSTR_VAL(name);
size_t key_len = ZSTR_LEN(name);

intern = Z_OBJ_DOCUMENT(object);
php_phongo_document_t* intern = Z_OBJ_DOCUMENT(object);

return php_phongo_document_has(intern, key, key_len);
return php_phongo_document_has(intern, ZSTR_VAL(member), ZSTR_LEN(member));
}

void php_phongo_document_unset_property(zend_object* object, zend_string* member, void** cache_slot)
Expand All @@ -588,21 +623,9 @@ void php_phongo_document_unset_property(zend_object* object, zend_string* member

zval* php_phongo_document_read_dimension(zend_object* object, zval* offset, int type, zval* rv)
{
php_phongo_document_t* intern;

intern = Z_OBJ_DOCUMENT(object);

if (Z_TYPE_P(offset) != IS_STRING) {
if (type == BP_VAR_IS) {
ZVAL_NULL(rv);
return rv;
}

phongo_throw_exception(PHONGO_ERROR_RUNTIME, "Could not find key of type \"%s\" in BSON document", zend_zval_type_name(offset));
return &EG(uninitialized_zval);
}
php_phongo_document_t* intern = Z_OBJ_DOCUMENT(object);

if (!php_phongo_document_get(intern, Z_STRVAL_P(offset), Z_STRLEN_P(offset), rv, type == BP_VAR_IS)) {
if (!php_phongo_document_get_by_zval(intern, offset, rv, type == BP_VAR_IS)) {
// Exception already thrown
return &EG(uninitialized_zval);
}
Expand All @@ -617,15 +640,9 @@ void php_phongo_document_write_dimension(zend_object* object, zval* offset, zval

int php_phongo_document_has_dimension(zend_object* object, zval* member, int check_empty)
{
php_phongo_document_t* intern;

intern = Z_OBJ_DOCUMENT(object);

if (Z_TYPE_P(member) != IS_STRING) {
return false;
}
php_phongo_document_t* intern = Z_OBJ_DOCUMENT(object);

return php_phongo_document_has(intern, Z_STRVAL_P(member), Z_STRLEN_P(member));
return php_phongo_document_has_by_zval(intern, member);
}

void php_phongo_document_unset_dimension(zend_object* object, zval* offset)
Expand Down
35 changes: 35 additions & 0 deletions tests/bson/bson-document-array-access-004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
MongoDB\BSON\Document array access with integers (dimension object accessors)
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

$document = MongoDB\BSON\Document::fromPHP([
'0' => 'foo',
'1' => 'bar',
]);

// Use a variable to assert that conversion doesn't affect the original zval
$key = 1;

var_dump(isset($document[0]));
var_dump(isset($document[$key]));
var_dump(isset($document[2]));

var_dump($document[0]);
var_dump($document[$key]);

var_dump($key);

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
bool(true)
bool(true)
bool(false)
string(3) "foo"
string(3) "bar"
int(1)
===DONE===
35 changes: 35 additions & 0 deletions tests/bson/bson-document-array-access-005.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
MongoDB\BSON\Document array access with integers (ArrayAccess methods)
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

$document = MongoDB\BSON\Document::fromPHP([
'0' => 'foo',
'1' => 'bar',
]);

// Use a variable to assert that conversion doesn't affect the original zval
$key = 1;

var_dump($document->offsetExists(0));
var_dump($document->offsetExists($key));
var_dump($document->offsetExists(2));

var_dump($document->offsetGet(0));
var_dump($document->offsetGet($key));

var_dump($key);

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
bool(true)
bool(true)
bool(false)
string(3) "foo"
string(3) "bar"
int(1)
===DONE===
6 changes: 0 additions & 6 deletions tests/bson/bson-document-array-access_error-003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ $document = MongoDB\BSON\Document::fromPHP([
'int64' => new MongoDB\BSON\Int64(123),
]);

echo throws(function() use ($document) {
$document[0];
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";

echo throws(function() use ($document) {
$document[0.1];
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";
Expand All @@ -28,8 +24,6 @@ echo throws(function() use ($document) {
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\RuntimeException
Could not find key of type "int" in BSON document
OK: Got MongoDB\Driver\Exception\RuntimeException
Could not find key of type "float" in BSON document
OK: Got MongoDB\Driver\Exception\RuntimeException
Could not find key of type "bool" in BSON document
Expand Down
6 changes: 0 additions & 6 deletions tests/bson/bson-document-array-access_error-004.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ $document = MongoDB\BSON\Document::fromPHP([
'int64' => new MongoDB\BSON\Int64(123),
]);

echo throws(function() use ($document) {
$document->offsetGet(0);
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";

echo throws(function() use ($document) {
$document->offsetGet(0.1);
}, MongoDB\Driver\Exception\RuntimeException::class), "\n";
Expand All @@ -28,8 +24,6 @@ echo throws(function() use ($document) {
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\RuntimeException
Could not find key of type "int" in BSON document
OK: Got MongoDB\Driver\Exception\RuntimeException
Could not find key of type "float" in BSON document
OK: Got MongoDB\Driver\Exception\RuntimeException
Could not find key of type "bool" in BSON document
Expand Down