@@ -179,21 +179,9 @@ bool php_phongo_bson_visit_after(const bson_iter_t *iter ARG_UNUSED, const char
179
179
}
180
180
/* }}} */
181
181
#endif
182
- void php_phongo_bson_visit_corrupt (const bson_iter_t * iter ARG_UNUSED , void * data ) /* {{{ */
182
+ void php_phongo_bson_visit_corrupt (const bson_iter_t * iter ARG_UNUSED , void * data ARG_UNUSED ) /* {{{ */
183
183
{
184
- #if PHP_VERSION_ID >= 70000
185
- zval * retval = & ((php_phongo_bson_state * )data )-> zchild ;
186
- #else
187
- zval * retval = ((php_phongo_bson_state * )data )-> zchild ;
188
- #endif
189
-
190
184
mongoc_log (MONGOC_LOG_LEVEL_TRACE , MONGOC_LOG_DOMAIN , "Corrupt BSON data detected!" );
191
-
192
- #if PHP_VERSION_ID >= 70000
193
- zval_ptr_dtor (retval );
194
- #else
195
- zval_ptr_dtor (& retval );
196
- #endif
197
185
}
198
186
/* }}} */
199
187
bool php_phongo_bson_visit_double (const bson_iter_t * iter ARG_UNUSED , const char * key , double v_double , void * data ) /* {{{ */
@@ -612,7 +600,7 @@ bool php_phongo_bson_visit_document(const bson_iter_t *iter ARG_UNUSED, const ch
612
600
array_init (state .zchild );
613
601
#endif
614
602
615
- if (!bson_iter_visit_all (& child , & php_bson_visitors , & state )) {
603
+ if (!bson_iter_visit_all (& child , & php_bson_visitors , & state ) && ! child . err_off ) {
616
604
/* If php_phongo_bson_visit_binary() finds an ODM class, it should
617
605
* supersede a default type map and named document class. */
618
606
if (state .odm && state .map .document_type == PHONGO_TYPEMAP_NONE ) {
@@ -662,6 +650,12 @@ bool php_phongo_bson_visit_document(const bson_iter_t *iter ARG_UNUSED, const ch
662
650
Z_SET_REFCOUNT_P (state .zchild , 1 );
663
651
#endif
664
652
}
653
+ } else {
654
+ /* Iteration stopped prematurely due to corruption or a failed
655
+ * visitor. Free state.zchild, which we just initialized, and return
656
+ * true to stop iteration for our parent context. */
657
+ zval_ptr_dtor (& state .zchild );
658
+ return true;
665
659
}
666
660
}
667
661
@@ -691,7 +685,7 @@ bool php_phongo_bson_visit_array(const bson_iter_t *iter ARG_UNUSED, const char
691
685
array_init (state .zchild );
692
686
#endif
693
687
694
- if (!bson_iter_visit_all (& child , & php_bson_visitors , & state )) {
688
+ if (!bson_iter_visit_all (& child , & php_bson_visitors , & state ) && ! child . err_off ) {
695
689
696
690
switch (state .map .array_type ) {
697
691
case PHONGO_TYPEMAP_CLASS : {
@@ -737,6 +731,12 @@ bool php_phongo_bson_visit_array(const bson_iter_t *iter ARG_UNUSED, const char
737
731
#endif
738
732
break ;
739
733
}
734
+ } else {
735
+ /* Iteration stopped prematurely due to corruption or a failed
736
+ * visitor. Free state.zchild, which we just initialized, and return
737
+ * true to stop iteration for our parent context. */
738
+ zval_ptr_dtor (& state .zchild );
739
+ return true;
740
740
}
741
741
742
742
}
@@ -1385,7 +1385,15 @@ PHONGO_API int phongo_bson_to_zval_ex(const unsigned char *data, int data_len, p
1385
1385
#else
1386
1386
array_init (state -> zchild );
1387
1387
#endif
1388
- bson_iter_visit_all (& iter , & php_bson_visitors , state );
1388
+
1389
+ if (bson_iter_visit_all (& iter , & php_bson_visitors , state ) || iter .err_off ) {
1390
+ /* Iteration stopped prematurely due to corruption or a failed visitor.
1391
+ * While we free the reader, state->zchild should be left as-is, since
1392
+ * the calling code may want to zval_ptr_dtor() it. */
1393
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Could not convert BSON document to a PHP variable" );
1394
+ bson_reader_destroy (reader );
1395
+ return 0 ;
1396
+ }
1389
1397
1390
1398
/* If php_phongo_bson_visit_binary() finds an ODM class, it should supersede
1391
1399
* a default type map and named root class. */
0 commit comments