[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Hash seed breaks 5.8.1 binary API; fix suggested

I've found (with Walt Mankowski's help[*]) the probable explanation for
why some modules -- most notably HTML::Parser -- break when Perl is
upgraded from 5.8.0 to 5.8.1.  The hash seeding implementation has
broken the binary API.  (Walt had the presence of mind to test with
PERL_HASH_SEED=0 and found that it fixed the breakage.)

Note that I say 5.8.1 broke the *binary* API.  The *source* API is
compatible, which is why rebuilding HTML::Parser fixes the problems.

The problem originates in the placement of the code to add the seed to
the hash.  The traditional (unchanged) hash value should have been
passed as always to the functions that expect it (e.g. hv_fetch_ent()),
but instead it was made a part of the PERL_HASH() macro.  Essentially
the binary API changed - functions that used to expect a hash based on
a string now expect a hash based on a string plus a global variable
that didn't even exist before 5.8.1.

I suggest we fix this problem in 5.8.2 (which should be released
quickly) in the following fashion:

  1. Decree that PL_hash_seed should forever and ever be zero.
     This will make 5.8.0 and 5.8.1 PERL_HASH() calculate the same
     value at all times.

  2. Create a new variable PL_new_hash_seed which is initialized with
     the methods currently used for PL_hash_seed.

  3. Add (or xor or whatever) PL_new_hash_seed with the user-provided
     hash value *inside* the functions that use hashes, *not* outside

These changes should make 5.8.2 both source and binary compatible with
both 5.8.0. and 5.8.1.
Chip Salzenberg               - a.k.a. -               <chip@pobox.com>
"I wanted to play hopscotch with the impenetrable mystery of existence,
    but he stepped in a wormhole and had to go in early."  // MST3K

Reply to: