@@ -82,6 +82,15 @@ void spl_SplObjectStorage_free_storage(zend_object *object) /* {{{ */
8282 zend_hash_destroy (& intern -> storage );
8383} /* }}} */
8484
85+ static zend_result spl_check_data_class (zend_object * obj )
86+ {
87+ if (UNEXPECTED (obj -> ce -> ce_flags & ZEND_ACC_DATA_CLASS )) {
88+ zend_type_error ("Instance of data class %s may not be used as key" , ZSTR_VAL (obj -> ce -> name ));
89+ return FAILURE ;
90+ }
91+ return SUCCESS ;
92+ }
93+
8594static zend_result spl_object_storage_get_hash (zend_hash_key * key , spl_SplObjectStorage * intern , zend_object * obj ) {
8695 if (UNEXPECTED (intern -> fptr_get_hash )) {
8796 zval param ;
@@ -437,11 +446,24 @@ PHP_METHOD(SplObjectStorage, attach)
437446 Z_PARAM_OPTIONAL
438447 Z_PARAM_ZVAL (inf )
439448 ZEND_PARSE_PARAMETERS_END ();
449+
450+ if (UNEXPECTED (spl_check_data_class (obj ) == FAILURE )) {
451+ RETURN_THROWS ();
452+ }
453+
440454 spl_object_storage_attach (intern , obj , inf );
441455} /* }}} */
442456
443457static int spl_object_storage_has_dimension (zend_object * object , zval * offset , int check_empty )
444458{
459+ if (EXPECTED (offset )) {
460+ ZVAL_DEREF (offset );
461+ if (Z_TYPE_P (offset ) == IS_OBJECT
462+ && UNEXPECTED (spl_check_data_class (Z_OBJ_P (offset )) == FAILURE )) {
463+ return 0 ;
464+ }
465+ }
466+
445467 spl_SplObjectStorage * intern = spl_object_storage_from_obj (object );
446468 if (UNEXPECTED (offset == NULL || Z_TYPE_P (offset ) != IS_OBJECT || (intern -> flags & SOS_OVERRIDDEN_READ_DIMENSION ))) {
447469 /* Can't optimize empty()/isset() check if getHash, offsetExists, or offsetGet is overridden */
@@ -461,6 +483,14 @@ static int spl_object_storage_has_dimension(zend_object *object, zval *offset, i
461483
462484static zval * spl_object_storage_read_dimension (zend_object * object , zval * offset , int type , zval * rv )
463485{
486+ if (EXPECTED (offset )) {
487+ ZVAL_DEREF (offset );
488+ if (Z_TYPE_P (offset ) == IS_OBJECT
489+ && UNEXPECTED (spl_check_data_class (Z_OBJ_P (offset )) == FAILURE )) {
490+ return NULL ;
491+ }
492+ }
493+
464494 spl_SplObjectStorage * intern = spl_object_storage_from_obj (object );
465495 if (UNEXPECTED (offset == NULL || Z_TYPE_P (offset ) != IS_OBJECT || (intern -> flags & SOS_OVERRIDDEN_READ_DIMENSION ))) {
466496 /* Can't optimize it if getHash, offsetExists, or offsetGet is overridden */
@@ -484,6 +514,14 @@ static zval *spl_object_storage_read_dimension(zend_object *object, zval *offset
484514
485515static void spl_object_storage_write_dimension (zend_object * object , zval * offset , zval * inf )
486516{
517+ if (EXPECTED (offset )) {
518+ ZVAL_DEREF (offset );
519+ if (Z_TYPE_P (offset ) == IS_OBJECT
520+ && UNEXPECTED (spl_check_data_class (Z_OBJ_P (offset )) == FAILURE )) {
521+ return ;
522+ }
523+ }
524+
487525 spl_SplObjectStorage * intern = spl_object_storage_from_obj (object );
488526 if (UNEXPECTED (offset == NULL || Z_TYPE_P (offset ) != IS_OBJECT || (intern -> flags & SOS_OVERRIDDEN_WRITE_DIMENSION ))) {
489527 zend_std_write_dimension (object , offset , inf );
@@ -494,6 +532,14 @@ static void spl_object_storage_write_dimension(zend_object *object, zval *offset
494532
495533static void spl_object_storage_unset_dimension (zend_object * object , zval * offset )
496534{
535+ if (EXPECTED (offset )) {
536+ ZVAL_DEREF (offset );
537+ if (Z_TYPE_P (offset ) == IS_OBJECT
538+ && UNEXPECTED (spl_check_data_class (Z_OBJ_P (offset )) == FAILURE )) {
539+ return ;
540+ }
541+ }
542+
497543 spl_SplObjectStorage * intern = spl_object_storage_from_obj (object );
498544 if (UNEXPECTED (Z_TYPE_P (offset ) != IS_OBJECT || (intern -> flags & SOS_OVERRIDDEN_UNSET_DIMENSION ))) {
499545 zend_std_unset_dimension (object , offset );
@@ -511,6 +557,11 @@ PHP_METHOD(SplObjectStorage, detach)
511557 ZEND_PARSE_PARAMETERS_START (1 , 1 )
512558 Z_PARAM_OBJ (obj )
513559 ZEND_PARSE_PARAMETERS_END ();
560+
561+ if (UNEXPECTED (spl_check_data_class (obj ) == FAILURE )) {
562+ RETURN_THROWS ();
563+ }
564+
514565 spl_object_storage_detach (intern , obj );
515566
516567 zend_hash_internal_pointer_reset_ex (& intern -> storage , & intern -> pos );
@@ -526,6 +577,10 @@ PHP_METHOD(SplObjectStorage, getHash)
526577 Z_PARAM_OBJ (obj )
527578 ZEND_PARSE_PARAMETERS_END ();
528579
580+ if (UNEXPECTED (spl_check_data_class (obj ) == FAILURE )) {
581+ RETURN_THROWS ();
582+ }
583+
529584 RETURN_NEW_STR (php_spl_object_hash (obj ));
530585
531586} /* }}} */
@@ -542,6 +597,10 @@ PHP_METHOD(SplObjectStorage, offsetGet)
542597 Z_PARAM_OBJ (obj )
543598 ZEND_PARSE_PARAMETERS_END ();
544599
600+ if (UNEXPECTED (spl_check_data_class (obj ) == FAILURE )) {
601+ RETURN_THROWS ();
602+ }
603+
545604 if (spl_object_storage_get_hash (& key , intern , obj ) == FAILURE ) {
546605 RETURN_NULL ();
547606 }
@@ -637,6 +696,11 @@ PHP_METHOD(SplObjectStorage, contains)
637696 ZEND_PARSE_PARAMETERS_START (1 , 1 )
638697 Z_PARAM_OBJ (obj )
639698 ZEND_PARSE_PARAMETERS_END ();
699+
700+ if (UNEXPECTED (spl_check_data_class (obj ) == FAILURE )) {
701+ RETURN_THROWS ();
702+ }
703+
640704 RETURN_BOOL (spl_object_storage_contains (intern , obj ));
641705} /* }}} */
642706
0 commit comments