@@ -1281,123 +1281,104 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t *uri, bson_t *option
12811281 return true;
12821282} /* }}} */
12831283
1284- static bool php_phongo_apply_ssl_opts ( mongoc_client_t * client , zval * zdriverOptions TSRMLS_DC )
1284+ static inline char * php_phongo_fetch_ssl_opt_string ( zval * zoptions , const char * key , int key_len )
12851285{
1286- mongoc_ssl_opt_t ssl_opt = {0 };
1287- zval * zoptions ;
1288- zend_bool free_pem_file = 0 , free_pem_pwd = 0 , free_ca_file = 0 , free_ca_dir = 0 , free_crl_file = 0 ;
1289- int plen ;
1290- bool valid_options ;
1286+ int plen ;
1287+ zend_bool pfree ;
1288+ char * pval , * value ;
12911289
1292- if (!zdriverOptions ) {
1293- return false;
1294- }
1295-
1296- zoptions = zdriverOptions ;
1297-
1298- /* Use SSL context options if provided for backwards compatibility */
1299- if (php_array_existsc (zdriverOptions , "context" )) {
1300- php_stream_context * context ;
1301- zval * zcontext ;
1290+ pval = php_array_fetchl_string (zoptions , key , key_len , & plen , & pfree );
1291+ value = pfree ? pval : estrndup (pval , plen );
13021292
1303- zcontext = php_array_fetchc (zdriverOptions , "context" );
1293+ return value ;
1294+ }
13041295
1305- context = php_stream_context_from_zval (zcontext , 1 );
1296+ static mongoc_ssl_opt_t * php_phongo_make_ssl_opt (zval * zoptions TSRMLS_DC )
1297+ {
1298+ mongoc_ssl_opt_t * ssl_opt ;
13061299
1307- if (!context ) {
1308- phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "\"context\" driver option is not a valid Stream-Context resource" );
1309- return false;
1310- }
1300+ if (!zoptions ) {
1301+ return NULL ;
1302+ }
13111303
1312- #if PHP_VERSION_ID >= 70000
1313- zoptions = php_array_fetchc_array (& context -> options , "ssl" );
1314- #else
1315- zoptions = php_array_fetchc_array (context -> options , "ssl" );
1304+ #if defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL ) || defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT )
1305+ if (php_array_existsc (zoptions , "ca_dir" ) || php_array_existsc (zoptions , "capath" )) {
1306+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "\"ca_dir\" and \"capath\" options are not supported by Secure Channel and Secure Transport" );
1307+ return NULL ;
1308+ }
13161309#endif
13171310
1318- if (!zoptions ) {
1319- phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Stream-Context resource does not contain \"ssl\" options array" );
1320- return false;
1321- }
1322- }
1311+ ssl_opt = ecalloc (1 , sizeof (mongoc_ssl_opt_t ));
13231312
13241313 /* Check canonical option names first and fall back to SSL context options
13251314 * for backwards compatibility. */
13261315 if (php_array_existsc (zoptions , "allow_invalid_hostname" )) {
1327- ssl_opt . allow_invalid_hostname = php_array_fetchc_bool (zoptions , "allow_invalid_hostname" );
1316+ ssl_opt -> allow_invalid_hostname = php_array_fetchc_bool (zoptions , "allow_invalid_hostname" );
13281317 }
13291318
13301319 if (php_array_existsc (zoptions , "weak_cert_validation" )) {
1331- ssl_opt . weak_cert_validation = php_array_fetchc_bool (zoptions , "weak_cert_validation" );
1320+ ssl_opt -> weak_cert_validation = php_array_fetchc_bool (zoptions , "weak_cert_validation" );
13321321 } else if (php_array_existsc (zoptions , "allow_self_signed" )) {
1333- ssl_opt . weak_cert_validation = php_array_fetchc_bool (zoptions , "allow_self_signed" );
1322+ ssl_opt -> weak_cert_validation = php_array_fetchc_bool (zoptions , "allow_self_signed" );
13341323 }
13351324
13361325 if (php_array_existsc (zoptions , "pem_file" )) {
1337- ssl_opt . pem_file = php_array_fetchc_string (zoptions , "pem_file" , & plen , & free_pem_file );
1326+ ssl_opt -> pem_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "pem_file" ) );
13381327 } else if (php_array_existsc (zoptions , "local_cert" )) {
1339- ssl_opt . pem_file = php_array_fetchc_string (zoptions , "local_cert" , & plen , & free_pem_file );
1328+ ssl_opt -> pem_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "local_cert" ) );
13401329 }
13411330
13421331 if (php_array_existsc (zoptions , "pem_pwd" )) {
1343- ssl_opt . pem_pwd = php_array_fetchc_string (zoptions , "pem_pwd" , & plen , & free_pem_pwd );
1332+ ssl_opt -> pem_pwd = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "pem_pwd" ) );
13441333 } else if (php_array_existsc (zoptions , "passphrase" )) {
1345- ssl_opt . pem_pwd = php_array_fetchc_string (zoptions , "passphrase" , & plen , & free_pem_pwd );
1334+ ssl_opt -> pem_pwd = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "passphrase" ) );
13461335 }
13471336
13481337 if (php_array_existsc (zoptions , "ca_file" )) {
1349- ssl_opt . ca_file = php_array_fetchc_string (zoptions , "ca_file" , & plen , & free_ca_file );
1338+ ssl_opt -> ca_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "ca_file" ) );
13501339 } else if (php_array_existsc (zoptions , "cafile" )) {
1351- ssl_opt . ca_file = php_array_fetchc_string (zoptions , "cafile" , & plen , & free_ca_file );
1340+ ssl_opt -> ca_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "cafile" ) );
13521341 }
13531342
13541343 if (php_array_existsc (zoptions , "ca_dir" )) {
1355- ssl_opt . ca_dir = php_array_fetchc_string (zoptions , "ca_dir" , & plen , & free_ca_dir );
1344+ ssl_opt -> ca_dir = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "ca_dir" ) );
13561345 } else if (php_array_existsc (zoptions , "capath" )) {
1357- ssl_opt . ca_dir = php_array_fetchc_string (zoptions , "capath" , & plen , & free_ca_dir );
1346+ ssl_opt -> ca_dir = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "capath" ) );
13581347 }
13591348
13601349 if (php_array_existsc (zoptions , "crl_file" )) {
1361- ssl_opt . crl_file = php_array_fetchc_string (zoptions , "crl_file" , & plen , & free_crl_file );
1350+ ssl_opt -> crl_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ( "crl_file" ) );
13621351 }
13631352
1364- valid_options = true;
1365-
1366- #if defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL ) || defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT )
1367- if (ssl_opt .ca_dir ) {
1368- phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "\"ca_dir\" and \"capath\" options are not supported by Secure Channel and Secure Transport" );
1369- valid_options = false;
1370- }
1371- #endif
1372-
1373- if (valid_options ) {
1374- mongoc_client_set_ssl_opts (client , & ssl_opt );
1375- }
1353+ return ssl_opt ;
1354+ }
13761355
1377- if (free_pem_file ) {
1378- str_efree (ssl_opt .pem_file );
1356+ static void php_phongo_free_ssl_opt (mongoc_ssl_opt_t * ssl_opt )
1357+ {
1358+ if (ssl_opt -> pem_file ) {
1359+ str_efree (ssl_opt -> pem_file );
13791360 }
13801361
1381- if (free_pem_pwd ) {
1382- str_efree (ssl_opt . pem_pwd );
1362+ if (ssl_opt -> pem_pwd ) {
1363+ str_efree (ssl_opt -> pem_pwd );
13831364 }
13841365
1385- if (free_ca_file ) {
1386- str_efree (ssl_opt . ca_file );
1366+ if (ssl_opt -> ca_file ) {
1367+ str_efree (ssl_opt -> ca_file );
13871368 }
13881369
1389- if (free_ca_dir ) {
1390- str_efree (ssl_opt . ca_dir );
1370+ if (ssl_opt -> ca_dir ) {
1371+ str_efree (ssl_opt -> ca_dir );
13911372 }
13921373
1393- if (free_crl_file ) {
1394- str_efree (ssl_opt . crl_file );
1374+ if (ssl_opt -> crl_file ) {
1375+ str_efree (ssl_opt -> crl_file );
13951376 }
13961377
1397- return valid_options ;
1378+ efree ( ssl_opt ) ;
13981379}
13991380
1400- static mongoc_client_t * php_phongo_make_mongo_client (const mongoc_uri_t * uri , zval * driverOptions TSRMLS_DC ) /* {{{ */
1381+ static mongoc_client_t * php_phongo_make_mongo_client (const mongoc_uri_t * uri , mongoc_ssl_opt_t * ssl_opt TSRMLS_DC ) /* {{{ */
14011382{
14021383 const char * mongoc_version , * bson_version ;
14031384 mongoc_client_t * client ;
@@ -1429,42 +1410,63 @@ static mongoc_client_t *php_phongo_make_mongo_client(const mongoc_uri_t *uri, zv
14291410 return NULL ;
14301411 }
14311412
1432- if (mongoc_uri_get_ssl (uri ) && driverOptions ) {
1433- if (!php_phongo_apply_ssl_opts (client , driverOptions TSRMLS_CC )) {
1434- mongoc_client_destroy (client );
1435- return NULL ;
1436- }
1413+ if (mongoc_uri_get_ssl (uri ) && ssl_opt ) {
1414+ mongoc_client_set_ssl_opts (client , ssl_opt );
14371415 }
14381416
14391417 return client ;
14401418} /* }}} */
14411419
1442- bool phongo_manager_init (php_phongo_manager_t * manager , const char * uri_string , bson_t * bson_options , zval * driverOptions TSRMLS_DC ) /* {{{ */
1420+ void phongo_manager_init (php_phongo_manager_t * manager , const char * uri_string , zval * options , zval * driverOptions TSRMLS_DC ) /* {{{ */
14431421{
1444- mongoc_uri_t * uri ;
1422+ bson_t bson_options = BSON_INITIALIZER ;
1423+ mongoc_uri_t * uri = NULL ;
1424+ mongoc_ssl_opt_t * ssl_opt = NULL ;
1425+
1426+ if (options ) {
1427+ phongo_zval_to_bson (options , PHONGO_BSON_NONE , & bson_options , NULL TSRMLS_CC );
1428+ }
1429+
1430+ /* An exception may be thrown during BSON conversion */
1431+ if (EG (exception )) {
1432+ goto cleanup ;
1433+ }
14451434
1446- if (!(uri = php_phongo_make_uri (uri_string , bson_options ))) {
1435+ if (!(uri = php_phongo_make_uri (uri_string , & bson_options ))) {
14471436 phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Failed to parse MongoDB URI: '%s'" , uri_string );
1448- return false ;
1437+ goto cleanup ;
14491438 }
14501439
1451- if (!php_phongo_apply_rc_options_to_uri (uri , bson_options TSRMLS_CC ) ||
1452- !php_phongo_apply_rp_options_to_uri (uri , bson_options TSRMLS_CC ) ||
1453- !php_phongo_apply_wc_options_to_uri (uri , bson_options TSRMLS_CC )) {
1440+ if (!php_phongo_apply_rc_options_to_uri (uri , & bson_options TSRMLS_CC ) ||
1441+ !php_phongo_apply_rp_options_to_uri (uri , & bson_options TSRMLS_CC ) ||
1442+ !php_phongo_apply_wc_options_to_uri (uri , & bson_options TSRMLS_CC )) {
14541443 /* Exception should already have been thrown */
1455- mongoc_uri_destroy (uri );
1456- return false;
1444+ goto cleanup ;
1445+ }
1446+
1447+ ssl_opt = php_phongo_make_ssl_opt (driverOptions TSRMLS_CC );
1448+
1449+ /* An exception may be thrown during SSL option creation */
1450+ if (EG (exception )) {
1451+ goto cleanup ;
14571452 }
14581453
1459- manager -> client = php_phongo_make_mongo_client (uri , driverOptions TSRMLS_CC );
1460- mongoc_uri_destroy (uri );
1454+ manager -> client = php_phongo_make_mongo_client (uri , ssl_opt TSRMLS_CC );
14611455
14621456 if (!manager -> client ) {
14631457 phongo_throw_exception (PHONGO_ERROR_RUNTIME TSRMLS_CC , "Failed to create Manager from URI: '%s'" , uri_string );
1464- return false;
14651458 }
14661459
1467- return true;
1460+ cleanup :
1461+ bson_destroy (& bson_options );
1462+
1463+ if (uri ) {
1464+ mongoc_uri_destroy (uri );
1465+ }
1466+
1467+ if (ssl_opt ) {
1468+ php_phongo_free_ssl_opt (ssl_opt );
1469+ }
14681470} /* }}} */
14691471
14701472void php_phongo_new_utcdatetime_from_epoch (zval * object , int64_t msec_since_epoch TSRMLS_DC ) /* {{{ */
0 commit comments