@@ -36,6 +36,20 @@ static void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t
3636static void phongo_clientencryption_encrypt (php_phongo_clientencryption_t * clientencryption , zval * zvalue , zval * zciphertext , zval * options );
3737static void phongo_clientencryption_decrypt (php_phongo_clientencryption_t * clientencryption , zval * zciphertext , zval * zvalue );
3838
39+ /* {{{ proto void MongoDB\Driver\ClientEncryption::__construct(array $options)
40+ Constructs a new ClientEncryption */
41+ static PHP_METHOD (ClientEncryption , __construct )
42+ {
43+ zval * options ;
44+
45+ PHONGO_PARSE_PARAMETERS_START (1 , 1 )
46+ Z_PARAM_ARRAY (options )
47+ PHONGO_PARSE_PARAMETERS_END ();
48+
49+ /* An exception will be thrown on error. */
50+ phongo_clientencryption_init (Z_CLIENTENCRYPTION_OBJ_P (getThis ()), options , NULL );
51+ } /* }}} */
52+
3953/* {{{ proto MongoDB\BSON\Binary MongoDB\Driver\ClientEncryption::createDataKey(string $kmsProvider[, array $options])
4054 Creates a new key document and inserts into the key vault collection. */
4155static PHP_METHOD (ClientEncryption , createDataKey )
@@ -99,6 +113,10 @@ static PHP_METHOD(ClientEncryption, decrypt)
99113 phongo_clientencryption_decrypt (intern , ciphertext , return_value );
100114} /* }}} */
101115
116+ ZEND_BEGIN_ARG_INFO_EX (ai_ClientEncryption___construct , 0 , 0 , 0 )
117+ ZEND_ARG_ARRAY_INFO (0 , options , 1 )
118+ ZEND_END_ARG_INFO ()
119+
102120ZEND_BEGIN_ARG_INFO_EX (ai_ClientEncryption_createDataKey , 0 , 0 , 1 )
103121 ZEND_ARG_INFO (0 , kmsProvider )
104122 ZEND_ARG_ARRAY_INFO (0 , options , 1 )
@@ -118,10 +136,10 @@ ZEND_END_ARG_INFO()
118136
119137static zend_function_entry php_phongo_clientencryption_me [] = {
120138 /* clang-format off */
139+ PHP_ME (ClientEncryption , __construct , ai_ClientEncryption___construct , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
121140 PHP_ME (ClientEncryption , createDataKey , ai_ClientEncryption_createDataKey , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
122141 PHP_ME (ClientEncryption , encrypt , ai_ClientEncryption_encrypt , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
123142 PHP_ME (ClientEncryption , decrypt , ai_ClientEncryption_decrypt , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
124- ZEND_NAMED_ME (__construct , PHP_FN (MongoDB_disabled___construct ), ai_ClientEncryption_void , ZEND_ACC_PRIVATE | ZEND_ACC_FINAL )
125143 ZEND_NAMED_ME (__wakeup , PHP_FN (MongoDB_disabled___wakeup ), ai_ClientEncryption_void , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
126144 PHP_FE_END
127145 /* clang-format on */
@@ -197,14 +215,13 @@ void php_phongo_clientencryption_init_ce(INIT_FUNC_ARGS) /* {{{ */
197215} /* }}} */
198216
199217#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
200- /* keyVaultClientManager is an output parameter and will be assigned the
201- * keyVaultNamespace Manager (if any) . */
202- static mongoc_client_encryption_opts_t * phongo_clientencryption_opts_from_zval (zval * defaultKeyVaultClient , zval * options , zval * * keyVaultClientManager ) /* {{{ */
218+ /* key_vault_client_manager is an output parameter and will be assigned to the
219+ * effective keyVaultClient . */
220+ static mongoc_client_encryption_opts_t * phongo_clientencryption_opts_from_zval (zval * options , zval * default_key_vault_client_manager , zval * * key_vault_client_manager ) /* {{{ */
203221{
204- mongoc_client_encryption_opts_t * opts ;
222+ mongoc_client_encryption_opts_t * opts = mongoc_client_encryption_opts_new () ;
205223
206- opts = mongoc_client_encryption_opts_new ();
207- * keyVaultClientManager = NULL ;
224+ * key_vault_client_manager = NULL ;
208225
209226 if (!options || Z_TYPE_P (options ) != IS_ARRAY ) {
210227 /* Returning opts as-is will defer to mongoc_client_encryption_new to
@@ -221,10 +238,15 @@ static mongoc_client_encryption_opts_t* phongo_clientencryption_opts_from_zval(z
221238 }
222239
223240 mongoc_client_encryption_opts_set_keyvault_client (opts , Z_MANAGER_OBJ_P (key_vault_client )-> client );
224- * keyVaultClientManager = key_vault_client ;
241+ * key_vault_client_manager = key_vault_client ;
242+ } else if (default_key_vault_client_manager ) {
243+ mongoc_client_encryption_opts_set_keyvault_client (opts , Z_MANAGER_OBJ_P (default_key_vault_client_manager )-> client );
244+ * key_vault_client_manager = default_key_vault_client_manager ;
225245 } else {
226- mongoc_client_encryption_opts_set_keyvault_client (opts , Z_MANAGER_OBJ_P (defaultKeyVaultClient )-> client );
227- * keyVaultClientManager = defaultKeyVaultClient ;
246+ /* If the ClientEncryption object is being constructed directly, the
247+ * "keyVaultClient" option must be explicitly provided. */
248+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT , "The \"keyVaultClient\" option is required when constructing a ClientEncryption object directly" );
249+ goto cleanup ;
228250 }
229251
230252 if (php_array_existsc (options , "keyVaultNamespace" )) {
@@ -301,32 +323,35 @@ static mongoc_client_encryption_opts_t* phongo_clientencryption_opts_from_zval(z
301323 return NULL ;
302324} /* }}} */
303325
304- void phongo_clientencryption_init (zval * return_value , zval * manager , zval * options ) /* {{{ */
326+ void phongo_clientencryption_init (php_phongo_clientencryption_t * intern , zval * options , zval * default_key_vault_client_manager ) /* {{{ */
305327{
306- php_phongo_clientencryption_t * intern ;
307328 mongoc_client_encryption_t * client_encryption ;
308329 mongoc_client_encryption_opts_t * opts ;
309- zval * key_vault_client_manager = manager ;
330+ zval * key_vault_client_manager = NULL ;
310331 bson_error_t error = { 0 };
311332
312- opts = phongo_clientencryption_opts_from_zval (manager , options , & key_vault_client_manager );
333+ opts = phongo_clientencryption_opts_from_zval (options , default_key_vault_client_manager , & key_vault_client_manager );
334+
313335 if (!opts ) {
314336 /* Exception already thrown */
315337 goto cleanup ;
316338 }
317339
318340 client_encryption = mongoc_client_encryption_new (opts , & error );
341+
319342 if (!client_encryption ) {
320343 phongo_throw_exception_from_bson_error_t (& error );
321-
322344 goto cleanup ;
323345 }
324346
325- object_init_ex (return_value , php_phongo_clientencryption_ce );
326-
327- intern = Z_CLIENTENCRYPTION_OBJ_P (return_value );
328347 intern -> client_encryption = client_encryption ;
329- ZVAL_ZVAL (& intern -> key_vault_client_manager , key_vault_client_manager , 1 , 0 );
348+
349+ /* Note: key_vault_client_manager should always be assigned if options were
350+ * successfully parsed by phongo_clientencryption_opts_from_zval, but let's
351+ * be defensive. */
352+ if (key_vault_client_manager ) {
353+ ZVAL_ZVAL (& intern -> key_vault_client_manager , key_vault_client_manager , 1 , 0 );
354+ }
330355
331356cleanup :
332357 if (opts ) {
@@ -584,7 +609,7 @@ static void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clien
584609 bson_value_destroy (& value );
585610} /* }}} */
586611#else /* MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION */
587- void phongo_clientencryption_init (zval * return_value , zval * manager , zval * options ) /* {{{ */
612+ void phongo_clientencryption_init (php_phongo_clientencryption_t * intern , zval * options , zval * default_key_vault_client_manager ) /* {{{ */
588613{
589614 phongo_throw_exception_no_cse (PHONGO_ERROR_RUNTIME , "Cannot configure clientEncryption object." );
590615}
0 commit comments