@@ -851,6 +851,12 @@ int _aaEqual(in TypeInfo tiRaw, in AA e1, in AA e2)
851
851
if (len != _aaLen(e2))
852
852
return 0 ;
853
853
854
+ // Bug 9852: at this point, e1 and e2 have the same length, so if one is
855
+ // null, the other must either also be null or have zero entries, so they
856
+ // must be equal. We check this here to avoid dereferencing null later on.
857
+ if (e1.impl is null || e2.impl is null )
858
+ return 1 ;
859
+
854
860
// Check for Bug 5925. ti_raw could be a TypeInfo_Const, we need to unwrap
855
861
// it until reaching a real TypeInfo_AssociativeArray.
856
862
const TypeInfo_AssociativeArray ti = _aaUnwrapTypeInfo(tiRaw);
@@ -864,6 +870,8 @@ int _aaEqual(in TypeInfo tiRaw, in AA e1, in AA e2)
864
870
const keyti = ti.key;
865
871
const valueti = ti.next;
866
872
const keysize = aligntsize(keyti.tsize);
873
+
874
+ assert (e2.impl ! is null );
867
875
const len2 = e2.impl.buckets.length;
868
876
869
877
int _aaKeys_x (const (Entry)* e)
@@ -994,3 +1002,25 @@ unittest
994
1002
995
1003
assert (aa1[key2a] == 200 );
996
1004
}
1005
+
1006
+ // Issue 9852
1007
+ unittest
1008
+ {
1009
+ // Original test case (revised, original assert was wrong)
1010
+ int [string ] a;
1011
+ a[" foo" ] = 0 ;
1012
+ a.remove(" foo" );
1013
+ assert (a == null ); // should not crash
1014
+
1015
+ int [string ] b;
1016
+ assert (b is null );
1017
+ assert (a == b); // should not deref null
1018
+ assert (b == a); // ditto
1019
+
1020
+ int [string ] c;
1021
+ c[" a" ] = 1 ;
1022
+ assert (a != c); // comparison with empty non-null AA
1023
+ assert (c != a);
1024
+ assert (b != c); // comparison with null AA
1025
+ assert (c != b);
1026
+ }
0 commit comments