mirror of
https://github.com/macintoshplus/mongo-php-driver.git
synced 2026-03-30 04:42:15 +02:00
PHPC-671: Avoid mongoc_client_t use-after-free by Cursor and Server
This commit is contained in:
53
php_phongo.c
53
php_phongo.c
@@ -224,7 +224,7 @@ static void php_phongo_log(mongoc_log_level_t log_level, const char *log_domain,
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Init objects */
|
||||
static void phongo_cursor_init(zval *return_value, mongoc_cursor_t *cursor, mongoc_client_t *client TSRMLS_DC) /* {{{ */
|
||||
static void phongo_cursor_init(zval *return_value, zval *manager, mongoc_cursor_t *cursor TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
php_phongo_cursor_t *intern;
|
||||
|
||||
@@ -233,18 +233,32 @@ static void phongo_cursor_init(zval *return_value, mongoc_cursor_t *cursor, mong
|
||||
intern = Z_CURSOR_OBJ_P(return_value);
|
||||
intern->cursor = cursor;
|
||||
intern->server_id = mongoc_cursor_get_hint(cursor);
|
||||
intern->client = client;
|
||||
intern->client = Z_MANAGER_OBJ_P(manager)->client;
|
||||
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
ZVAL_COPY(&intern->manager, manager);
|
||||
#else
|
||||
Z_ADDREF_P(manager);
|
||||
intern->manager = manager;
|
||||
#endif
|
||||
} /* }}} */
|
||||
|
||||
void phongo_server_init(zval *return_value, mongoc_client_t *client, int server_id TSRMLS_DC) /* {{{ */
|
||||
void phongo_server_init(zval *return_value, zval *manager, int server_id TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
php_phongo_server_t *server;
|
||||
|
||||
object_init_ex(return_value, php_phongo_server_ce);
|
||||
|
||||
server = Z_SERVER_OBJ_P(return_value);
|
||||
server->client = client;
|
||||
server->server_id = server_id;
|
||||
server->client = Z_MANAGER_OBJ_P(manager)->client;
|
||||
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
ZVAL_COPY(&server->manager, manager);
|
||||
#else
|
||||
Z_ADDREF_P(manager);
|
||||
server->manager = manager;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -467,7 +481,7 @@ zend_bool phongo_writeerror_init(zval *return_value, bson_t *bson TSRMLS_DC) /*
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
php_phongo_writeresult_t *phongo_writeresult_init(zval *return_value, bson_t *reply, mongoc_client_t *client, int server_id TSRMLS_DC) /* {{{ */
|
||||
php_phongo_writeresult_t *phongo_writeresult_init(zval *return_value, bson_t *reply, zval *manager, int server_id TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
php_phongo_writeresult_t *writeresult;
|
||||
|
||||
@@ -475,8 +489,15 @@ php_phongo_writeresult_t *phongo_writeresult_init(zval *return_value, bson_t *re
|
||||
|
||||
writeresult = Z_WRITERESULT_OBJ_P(return_value);
|
||||
writeresult->reply = bson_copy(reply);
|
||||
writeresult->client = client;
|
||||
writeresult->server_id = server_id;
|
||||
writeresult->client = Z_MANAGER_OBJ_P(manager)->client;
|
||||
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
ZVAL_COPY(&writeresult->manager, manager);
|
||||
#else
|
||||
Z_ADDREF_P(manager);
|
||||
writeresult->manager = manager;
|
||||
#endif
|
||||
|
||||
return writeresult;
|
||||
} /* }}} */
|
||||
@@ -506,8 +527,9 @@ mongoc_bulk_operation_t *phongo_bulkwrite_init(zend_bool ordered) { /* {{{ */
|
||||
return mongoc_bulk_operation_new(ordered);
|
||||
} /* }}} */
|
||||
|
||||
bool phongo_execute_write(mongoc_client_t *client, const char *namespace, mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */
|
||||
bool phongo_execute_write(zval *manager, const char *namespace, mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
mongoc_client_t *client;
|
||||
bson_error_t error;
|
||||
char *dbname;
|
||||
char *collname;
|
||||
@@ -515,6 +537,8 @@ bool phongo_execute_write(mongoc_client_t *client, const char *namespace, mongoc
|
||||
bson_t reply = BSON_INITIALIZER;
|
||||
php_phongo_writeresult_t *writeresult;
|
||||
|
||||
client = Z_MANAGER_OBJ_P(manager)->client;
|
||||
|
||||
if (!phongo_split_namespace(namespace, &dbname, &collname)) {
|
||||
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s: %s", "Invalid namespace provided", namespace);
|
||||
return false;
|
||||
@@ -553,7 +577,7 @@ bool phongo_execute_write(mongoc_client_t *client, const char *namespace, mongoc
|
||||
return false;
|
||||
}
|
||||
|
||||
writeresult = phongo_writeresult_init(return_value, &reply, client, bulk->hint TSRMLS_CC);
|
||||
writeresult = phongo_writeresult_init(return_value, &reply, manager, bulk->hint TSRMLS_CC);
|
||||
writeresult->write_concern = mongoc_write_concern_copy(write_concern);
|
||||
|
||||
/* The Write failed */
|
||||
@@ -571,14 +595,17 @@ bool phongo_execute_write(mongoc_client_t *client, const char *namespace, mongoc
|
||||
return success;
|
||||
} /* }}} */
|
||||
|
||||
int phongo_execute_query(mongoc_client_t *client, const char *namespace, const php_phongo_query_t *query, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */
|
||||
int phongo_execute_query(zval *manager, const char *namespace, const php_phongo_query_t *query, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
mongoc_client_t *client;
|
||||
const bson_t *doc = NULL;
|
||||
mongoc_cursor_t *cursor;
|
||||
char *dbname;
|
||||
char *collname;
|
||||
mongoc_collection_t *collection;
|
||||
|
||||
client = Z_MANAGER_OBJ_P(manager)->client;
|
||||
|
||||
if (!phongo_split_namespace(namespace, &dbname, &collname)) {
|
||||
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s: %s", "Invalid namespace provided", namespace);
|
||||
return false;
|
||||
@@ -626,17 +653,19 @@ int phongo_execute_query(mongoc_client_t *client, const char *namespace, const p
|
||||
return true;
|
||||
}
|
||||
|
||||
phongo_cursor_init(return_value, cursor, client TSRMLS_CC);
|
||||
phongo_cursor_init(return_value, manager, cursor TSRMLS_CC);
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
int phongo_execute_command(mongoc_client_t *client, const char *db, const bson_t *command, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */
|
||||
int phongo_execute_command(zval *manager, const char *db, const bson_t *command, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
mongoc_client_t *client;
|
||||
mongoc_cursor_t *cursor;
|
||||
const bson_t *doc;
|
||||
bson_iter_t iter;
|
||||
bson_iter_t child;
|
||||
|
||||
client = Z_MANAGER_OBJ_P(manager)->client;
|
||||
|
||||
cursor = mongoc_client_command(client, db, MONGOC_QUERY_NONE, 0, 1, 0, command, NULL, read_preference);
|
||||
if (server_id > 0) {
|
||||
@@ -702,7 +731,7 @@ int phongo_execute_command(mongoc_client_t *client, const char *db, const bson_t
|
||||
mongoc_cursor_next(cursor, &doc);
|
||||
}
|
||||
|
||||
phongo_cursor_init(return_value, cursor, client TSRMLS_CC);
|
||||
phongo_cursor_init(return_value, manager, cursor TSRMLS_CC);
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
|
||||
@@ -114,15 +114,15 @@ void phongo_throw_exception_from_bson_error_t(bson_error_t *error TSRMLS_DC);
|
||||
|
||||
PHONGO_API zend_object_handlers *phongo_get_std_object_handlers(void);
|
||||
|
||||
void phongo_server_init (zval *return_value, mongoc_client_t *client, int server_id TSRMLS_DC);
|
||||
void phongo_server_init (zval *return_value, zval *manager, int server_id TSRMLS_DC);
|
||||
void phongo_readconcern_init (zval *return_value, const mongoc_read_concern_t *read_concern TSRMLS_DC);
|
||||
void phongo_readpreference_init (zval *return_value, const mongoc_read_prefs_t *read_prefs TSRMLS_DC);
|
||||
void phongo_writeconcern_init (zval *return_value, const mongoc_write_concern_t *write_concern TSRMLS_DC);
|
||||
bool phongo_query_init (php_phongo_query_t *query, bson_t *filter, bson_t *options TSRMLS_DC);
|
||||
mongoc_bulk_operation_t* phongo_bulkwrite_init (zend_bool ordered);
|
||||
bool phongo_execute_write (mongoc_client_t *client, const char *namespace, mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern, int server_id, zval *return_value, int return_value_used TSRMLS_DC);
|
||||
int phongo_execute_command (mongoc_client_t *client, const char *db, const bson_t *command, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC);
|
||||
int phongo_execute_query (mongoc_client_t *client, const char *namespace, const php_phongo_query_t *query, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC);
|
||||
bool phongo_execute_write (zval *manager, const char *namespace, mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern, int server_id, zval *return_value, int return_value_used TSRMLS_DC);
|
||||
int phongo_execute_command (zval *manager, const char *db, const bson_t *command, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC);
|
||||
int phongo_execute_query (zval *manager, const char *namespace, const php_phongo_query_t *query, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC);
|
||||
|
||||
mongoc_stream_t* phongo_stream_initiator (const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error);
|
||||
const mongoc_read_concern_t* phongo_read_concern_from_zval (zval *zread_concern TSRMLS_DC);
|
||||
|
||||
@@ -40,6 +40,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
zend_object std;
|
||||
mongoc_cursor_t *cursor;
|
||||
zval *manager;
|
||||
mongoc_client_t *client;
|
||||
int server_id;
|
||||
php_phongo_bson_state visitor_data;
|
||||
@@ -80,6 +81,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
zend_object std;
|
||||
zval *manager;
|
||||
mongoc_client_t *client;
|
||||
int server_id;
|
||||
} php_phongo_server_t;
|
||||
@@ -113,6 +115,7 @@ typedef struct {
|
||||
zend_object std;
|
||||
mongoc_write_concern_t *write_concern;
|
||||
bson_t *reply;
|
||||
zval *manager;
|
||||
mongoc_client_t *client;
|
||||
int server_id;
|
||||
} php_phongo_writeresult_t;
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
mongoc_cursor_t *cursor;
|
||||
zval manager;
|
||||
mongoc_client_t *client;
|
||||
int server_id;
|
||||
php_phongo_bson_state visitor_data;
|
||||
@@ -79,6 +80,7 @@ typedef struct {
|
||||
} php_phongo_readpreference_t;
|
||||
|
||||
typedef struct {
|
||||
zval manager;
|
||||
mongoc_client_t *client;
|
||||
int server_id;
|
||||
zend_object std;
|
||||
@@ -112,6 +114,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
mongoc_write_concern_t *write_concern;
|
||||
bson_t *reply;
|
||||
zval manager;
|
||||
mongoc_client_t *client;
|
||||
int server_id;
|
||||
zend_object std;
|
||||
|
||||
@@ -157,8 +157,11 @@ PHP_METHOD(Cursor, getServer)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
phongo_server_init(return_value, intern->cursor->client, intern->server_id TSRMLS_CC);
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
phongo_server_init(return_value, &intern->manager, intern->server_id TSRMLS_CC);
|
||||
#else
|
||||
phongo_server_init(return_value, intern->manager, intern->server_id TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -222,6 +225,8 @@ static void php_phongo_cursor_free_object(phongo_free_object_arg *object TSRMLS_
|
||||
|
||||
php_phongo_cursor_free(intern);
|
||||
|
||||
zval_ptr_dtor(&intern->manager);
|
||||
|
||||
#if PHP_VERSION_ID < 70000
|
||||
efree(intern);
|
||||
#endif
|
||||
|
||||
@@ -89,7 +89,6 @@ PHP_METHOD(Manager, __construct)
|
||||
Execute a command */
|
||||
PHP_METHOD(Manager, executeCommand)
|
||||
{
|
||||
php_phongo_manager_t *intern;
|
||||
char *db;
|
||||
phongo_zpp_char_len db_len;
|
||||
zval *command;
|
||||
@@ -98,23 +97,19 @@ PHP_METHOD(Manager, executeCommand)
|
||||
DECLARE_RETURN_VALUE_USED
|
||||
SUPPRESS_UNUSED_WARNING(return_value_ptr)
|
||||
|
||||
|
||||
intern = Z_MANAGER_OBJ_P(getThis());
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &db, &db_len, &command, php_phongo_command_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
cmd = Z_COMMAND_OBJ_P(command);
|
||||
phongo_execute_command(intern->client, db, cmd->bson, phongo_read_preference_from_zval(readPreference TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC);
|
||||
phongo_execute_command(getThis(), db, cmd->bson, phongo_read_preference_from_zval(readPreference TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto MongoDB\Driver\Cursor Manager::executeQuery(string $namespace, MongoDB\Driver\Query $zquery[, MongoDB\Driver\ReadPreference $readPreference = null])
|
||||
Execute a Query */
|
||||
PHP_METHOD(Manager, executeQuery)
|
||||
{
|
||||
php_phongo_manager_t *intern;
|
||||
char *namespace;
|
||||
phongo_zpp_char_len namespace_len;
|
||||
zval *zquery;
|
||||
@@ -122,22 +117,18 @@ PHP_METHOD(Manager, executeQuery)
|
||||
DECLARE_RETURN_VALUE_USED
|
||||
SUPPRESS_UNUSED_WARNING(return_value_ptr)
|
||||
|
||||
|
||||
intern = Z_MANAGER_OBJ_P(getThis());
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &zquery, php_phongo_query_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
phongo_execute_query(intern->client, namespace, phongo_query_from_zval(zquery TSRMLS_CC), phongo_read_preference_from_zval(readPreference TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC);
|
||||
phongo_execute_query(getThis(), namespace, phongo_query_from_zval(zquery TSRMLS_CC), phongo_read_preference_from_zval(readPreference TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto MongoDB\Driver\WriteResult Manager::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, MongoDB\Driver\WriteConcern $writeConcern = null])
|
||||
Executes a write operation bulk (e.g. insert, update, delete) */
|
||||
PHP_METHOD(Manager, executeBulkWrite)
|
||||
{
|
||||
php_phongo_manager_t *intern;
|
||||
char *namespace;
|
||||
phongo_zpp_char_len namespace_len;
|
||||
zval *zbulk;
|
||||
@@ -146,16 +137,13 @@ PHP_METHOD(Manager, executeBulkWrite)
|
||||
DECLARE_RETURN_VALUE_USED
|
||||
SUPPRESS_UNUSED_WARNING(return_value_ptr)
|
||||
|
||||
|
||||
intern = Z_MANAGER_OBJ_P(getThis());
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &zwrite_concern, php_phongo_writeconcern_ce) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bulk = Z_BULKWRITE_OBJ_P(zbulk);
|
||||
phongo_execute_write(intern->client, namespace, bulk->bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC);
|
||||
phongo_execute_write(getThis(), namespace, bulk->bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -230,12 +218,12 @@ PHP_METHOD(Manager, getServers)
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
phongo_server_init(&obj, intern->client, ((mongoc_server_description_t *)set->items[i].item)->id TSRMLS_CC);
|
||||
phongo_server_init(&obj, getThis(), ((mongoc_server_description_t *)set->items[i].item)->id TSRMLS_CC);
|
||||
add_next_index_zval(return_value, &obj);
|
||||
#else
|
||||
MAKE_STD_ZVAL(obj);
|
||||
|
||||
phongo_server_init(obj, intern->client, sd->id TSRMLS_CC);
|
||||
phongo_server_init(obj, getThis(), sd->id TSRMLS_CC);
|
||||
add_next_index_zval(return_value, obj);
|
||||
#endif
|
||||
}
|
||||
@@ -281,7 +269,7 @@ PHP_METHOD(Manager, selectServer)
|
||||
readPreference = phongo_read_preference_from_zval(zreadPreference TSRMLS_CC);
|
||||
selected_server = mongoc_topology_select(intern->client->topology, MONGOC_SS_READ, readPreference, MONGOC_SS_DEFAULT_LOCAL_THRESHOLD_MS, &error);
|
||||
if (selected_server) {
|
||||
phongo_server_init(return_value, intern->client, selected_server->id TSRMLS_CC);
|
||||
phongo_server_init(return_value, getThis(), selected_server->id TSRMLS_CC);
|
||||
mongoc_server_description_destroy(selected_server);
|
||||
} else {
|
||||
/* Check for connection related exceptions */
|
||||
|
||||
@@ -80,7 +80,11 @@ PHP_METHOD(Server, executeCommand)
|
||||
|
||||
|
||||
cmd = Z_COMMAND_OBJ_P(command);
|
||||
phongo_execute_command(intern->client, db, cmd->bson, phongo_read_preference_from_zval(readPreference TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
phongo_execute_command(&intern->manager, db, cmd->bson, phongo_read_preference_from_zval(readPreference TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#else
|
||||
phongo_execute_command(intern->manager, db, cmd->bson, phongo_read_preference_from_zval(readPreference TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto MongoDB\Driver\Cursor Server::executeQuery(string $namespace, MongoDB\Driver\Query $zquery[, MongoDB\Driver\ReadPreference $readPreference = null]))
|
||||
@@ -102,8 +106,11 @@ PHP_METHOD(Server, executeQuery)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
phongo_execute_query(intern->client, namespace, phongo_query_from_zval(zquery TSRMLS_CC), phongo_read_preference_from_zval(readPreference TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
phongo_execute_query(&intern->manager, namespace, phongo_query_from_zval(zquery TSRMLS_CC), phongo_read_preference_from_zval(readPreference TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#else
|
||||
phongo_execute_query(intern->manager, namespace, phongo_query_from_zval(zquery TSRMLS_CC), phongo_read_preference_from_zval(readPreference TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto MongoDB\Driver\WriteResult Server::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, MongoDB\Driver\WriteConcern $writeConcern = null])
|
||||
@@ -128,7 +135,11 @@ PHP_METHOD(Server, executeBulkWrite)
|
||||
|
||||
|
||||
bulk = Z_BULKWRITE_OBJ_P(zbulk);
|
||||
phongo_execute_write(intern->client, namespace, bulk->bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
phongo_execute_write(&intern->manager, namespace, bulk->bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#else
|
||||
phongo_execute_write(intern->manager, namespace, bulk->bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto string Server::getHost()
|
||||
@@ -522,6 +533,8 @@ static void php_phongo_server_free_object(phongo_free_object_arg *object TSRMLS_
|
||||
|
||||
zend_object_std_dtor(&intern->std TSRMLS_CC);
|
||||
|
||||
zval_ptr_dtor(&intern->manager);
|
||||
|
||||
#if PHP_VERSION_ID < 70000
|
||||
efree(intern);
|
||||
#endif
|
||||
|
||||
@@ -155,8 +155,11 @@ PHP_METHOD(WriteResult, getServer)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC);
|
||||
#if PHP_VERSION_ID >= 70000
|
||||
phongo_server_init(return_value, &intern->manager, intern->server_id TSRMLS_CC);
|
||||
#else
|
||||
phongo_server_init(return_value, intern->manager, intern->server_id TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto array WriteResult::getUpsertedIds()
|
||||
@@ -422,6 +425,8 @@ static void php_phongo_writeresult_free_object(phongo_free_object_arg *object TS
|
||||
mongoc_write_concern_destroy(intern->write_concern);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&intern->manager);
|
||||
|
||||
#if PHP_VERSION_ID < 70000
|
||||
efree(intern);
|
||||
#endif
|
||||
|
||||
26
tests/cursor/bug0671-001.phpt
Normal file
26
tests/cursor/bug0671-001.phpt
Normal file
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
PHPC-671: Segfault if Manager is already freed when destructing live Cursor
|
||||
--SKIPIF--
|
||||
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once __DIR__ . "/../utils/basic.inc";
|
||||
|
||||
$manager = new MongoDB\Driver\Manager(STANDALONE);
|
||||
|
||||
$bulk = new MongoDB\Driver\BulkWrite();
|
||||
$bulk->insert(['_id' => 1]);
|
||||
$bulk->insert(['_id' => 2]);
|
||||
$bulk->insert(['_id' => 3]);
|
||||
$manager->executeBulkWrite(NS, $bulk);
|
||||
|
||||
$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2]));
|
||||
|
||||
unset($manager);
|
||||
unset($cursor);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
25
tests/server/bug0671-002.phpt
Normal file
25
tests/server/bug0671-002.phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
PHPC-671: Segfault if Manager is already freed when using selected Server
|
||||
--SKIPIF--
|
||||
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once __DIR__ . "/../utils/basic.inc";
|
||||
|
||||
$manager = new MongoDB\Driver\Manager(STANDALONE);
|
||||
$server = $manager->selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY));
|
||||
|
||||
unset($manager);
|
||||
|
||||
$cursor = $server->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
|
||||
var_dump($cursor->toArray()[0]);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
object(stdClass)#%d (%d) {
|
||||
["ok"]=>
|
||||
float(1)
|
||||
}
|
||||
===DONE===
|
||||
32
tests/writeResult/bug0671-003.phpt
Normal file
32
tests/writeResult/bug0671-003.phpt
Normal file
@@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
PHPC-671: Segfault if Manager is already freed when using WriteResult's Server
|
||||
--SKIPIF--
|
||||
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once __DIR__ . "/../utils/basic.inc";
|
||||
|
||||
$manager = new MongoDB\Driver\Manager(STANDALONE);
|
||||
|
||||
$bulk = new MongoDB\Driver\BulkWrite();
|
||||
$bulk->insert(['_id' => 1]);
|
||||
$writeResult = $manager->executeBulkWrite(NS, $bulk);
|
||||
|
||||
unset($manager);
|
||||
|
||||
$server = $writeResult->getServer();
|
||||
|
||||
/* WriteResult only uses the client to construct a Server. We need to interact
|
||||
* with the Server to test for a user-after-free. */
|
||||
$cursor = $server->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1]));
|
||||
var_dump($cursor->toArray()[0]);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
object(stdClass)#%d (%d) {
|
||||
["ok"]=>
|
||||
float(1)
|
||||
}
|
||||
===DONE===
|
||||
Reference in New Issue
Block a user