hash should not take into account non-sexp trailing data (bug report from Arthur Gleckler)

This commit is contained in:
Alex Shinn 2020-08-04 12:23:22 +09:00
parent 2e63c53a6b
commit b4520b31f5

View file

@ -48,7 +48,7 @@ sexp sexp_string_ci_hash (sexp ctx, sexp self, sexp_sint_t n, sexp str, sexp bou
} }
static sexp_uint_t hash_one (sexp ctx, sexp obj, sexp_uint_t bound, sexp_sint_t depth) { static sexp_uint_t hash_one (sexp ctx, sexp obj, sexp_uint_t bound, sexp_sint_t depth) {
sexp_uint_t acc = FNV_OFFSET_BASIS, size; sexp_uint_t acc = FNV_OFFSET_BASIS;
sexp_sint_t i, len; sexp_sint_t i, len;
sexp t, *p; sexp t, *p;
char *p0; char *p0;
@ -65,12 +65,7 @@ static sexp_uint_t hash_one (sexp ctx, sexp obj, sexp_uint_t bound, sexp_sint_t
p = (sexp*) (((char*)obj) + sexp_type_field_base(t)); p = (sexp*) (((char*)obj) + sexp_type_field_base(t));
p0 = ((char*)obj) + offsetof(struct sexp_struct, value); p0 = ((char*)obj) + offsetof(struct sexp_struct, value);
if ((sexp)p == obj) p=(sexp*)p0; if ((sexp)p == obj) p=(sexp*)p0;
/* hash trailing non-object data */ /* hash only eq-object slots */
size = sexp_type_size_of_object(t, obj)-offsetof(struct sexp_struct, value);
p0 = ((char*)p + sexp_type_num_slots_of_object(t,obj)*sizeof(sexp));
if (((char*)obj + size) > p0)
for (i=0; i<(sexp_sint_t)size; i++) {acc *= FNV_PRIME; acc ^= p0[i];}
/* hash eq-object slots */
len = sexp_type_num_eq_slots_of_object(t, obj); len = sexp_type_num_eq_slots_of_object(t, obj);
if (len > 0) { if (len > 0) {
depth--; depth--;
@ -170,7 +165,7 @@ static void sexp_regrow_hash_table (sexp ctx, sexp ht, sexp oldbuckets, sexp has
sexp_gc_var1(newbuckets); sexp_gc_var1(newbuckets);
sexp_gc_preserve1(ctx, newbuckets); sexp_gc_preserve1(ctx, newbuckets);
newbuckets = sexp_make_vector(ctx, sexp_make_fixnum(newsize), SEXP_NULL); newbuckets = sexp_make_vector(ctx, sexp_make_fixnum(newsize), SEXP_NULL);
if (newbuckets) { if (newbuckets && !sexp_exceptionp(newbuckets)) {
oldvec = sexp_vector_data(oldbuckets); oldvec = sexp_vector_data(oldbuckets);
newvec = sexp_vector_data(newbuckets); newvec = sexp_vector_data(newbuckets);
for (i=0; i<oldsize; i++) { for (i=0; i<oldsize; i++) {