@@ -571,12 +571,25 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
571
571
zval * data ;
572
572
573
573
if (flag & HASH_ADD ) {
574
- return NULL ;
575
- }
576
- ZEND_ASSERT (& p -> val != pData );
577
- data = & p -> val ;
578
- if ((flag & HASH_UPDATE_INDIRECT ) && Z_TYPE_P (data ) == IS_INDIRECT ) {
579
- data = Z_INDIRECT_P (data );
574
+ if (!(flag & HASH_UPDATE_INDIRECT )) {
575
+ return NULL ;
576
+ }
577
+ ZEND_ASSERT (& p -> val != pData );
578
+ data = & p -> val ;
579
+ if (Z_TYPE_P (data ) == IS_INDIRECT ) {
580
+ data = Z_INDIRECT_P (data );
581
+ if (Z_TYPE_P (data ) != IS_UNDEF ) {
582
+ return NULL ;
583
+ }
584
+ } else {
585
+ return NULL ;
586
+ }
587
+ } else {
588
+ ZEND_ASSERT (& p -> val != pData );
589
+ data = & p -> val ;
590
+ if ((flag & HASH_UPDATE_INDIRECT ) && Z_TYPE_P (data ) == IS_INDIRECT ) {
591
+ data = Z_INDIRECT_P (data );
592
+ }
580
593
}
581
594
HANDLE_BLOCK_INTERRUPTIONS ();
582
595
if (ht -> pDestructor ) {
@@ -1869,31 +1882,42 @@ ZEND_API void ZEND_FASTCALL _zend_hash_merge(HashTable *target, HashTable *sourc
1869
1882
IS_CONSISTENT (target );
1870
1883
HT_ASSERT (GC_REFCOUNT (target ) == 1 );
1871
1884
1872
- for (idx = 0 ; idx < source -> nNumUsed ; idx ++ ) {
1873
- p = source -> arData + idx ;
1874
- if (UNEXPECTED (Z_TYPE (p -> val ) == IS_UNDEF )) continue ;
1875
- if (p -> key ) {
1876
- if (EXPECTED ((t = zend_hash_find_ind (target , p -> key )) == NULL )) {
1877
- t = zend_hash_update_ind (target , p -> key , & p -> val );
1885
+ if (overwrite ) {
1886
+ for (idx = 0 ; idx < source -> nNumUsed ; idx ++ ) {
1887
+ p = source -> arData + idx ;
1888
+ if (UNEXPECTED (Z_TYPE (p -> val ) == IS_UNDEF )) continue ;
1889
+ if (UNEXPECTED (Z_TYPE (p -> val ) == IS_INDIRECT ) &&
1890
+ UNEXPECTED (Z_TYPE_P (Z_INDIRECT (p -> val )) == IS_UNDEF )) {
1891
+ continue ;
1892
+ }
1893
+ if (p -> key ) {
1894
+ t = _zend_hash_add_or_update_i (target , p -> key , & p -> val , HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_RELAY_CC );
1878
1895
if (t && pCopyConstructor ) {
1879
1896
pCopyConstructor (t );
1880
1897
}
1881
1898
} else {
1882
- if (!overwrite ) {
1883
- continue ;
1884
- }
1885
- if (target -> pDestructor ) {
1886
- target -> pDestructor (t );
1887
- }
1888
- ZVAL_COPY_VALUE (t , & p -> val );
1889
- if (pCopyConstructor ) {
1899
+ t = zend_hash_index_update (target , p -> h , & p -> val );
1900
+ if (t && pCopyConstructor ) {
1890
1901
pCopyConstructor (t );
1891
1902
}
1892
1903
}
1893
- } else {
1894
- if ((overwrite || !zend_hash_index_exists (target , p -> h ))) {
1895
- t = zend_hash_index_update (target , p -> h , & p -> val );
1896
- if (t && pCopyConstructor ) {
1904
+ }
1905
+ } else {
1906
+ for (idx = 0 ; idx < source -> nNumUsed ; idx ++ ) {
1907
+ p = source -> arData + idx ;
1908
+ if (UNEXPECTED (Z_TYPE (p -> val ) == IS_UNDEF )) continue ;
1909
+ if (UNEXPECTED (Z_TYPE (p -> val ) == IS_INDIRECT ) &&
1910
+ UNEXPECTED (Z_TYPE_P (Z_INDIRECT (p -> val )) == IS_UNDEF )) {
1911
+ continue ;
1912
+ }
1913
+ if (p -> key ) {
1914
+ t = _zend_hash_add_or_update_i (target , p -> key , & p -> val , HASH_ADD | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_RELAY_CC );
1915
+ if (t && pCopyConstructor ) {
1916
+ pCopyConstructor (t );
1917
+ }
1918
+ } else {
1919
+ t = zend_hash_index_add (target , p -> h , & p -> val );
1920
+ if (t && pCopyConstructor ) {
1897
1921
pCopyConstructor (t );
1898
1922
}
1899
1923
}
0 commit comments