From: Jarkko Hietaniemi Date: Fri, 17 May 2002 16:52:15 +0000 (+0000) Subject: PERL_HASH() casting games so that our hashed data is "unsigned X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5afd6d4225c4773e6506b9fc3c8ca61abeea89a5;p=p5sagit%2Fp5-mst-13.2.git PERL_HASH() casting games so that our hashed data is "unsigned char" but old code using just a "char" doesn't need changes. (The change is using a temporary pointer instead of a direct cast to unsigned char* which would blindly cast anything, not just char pointers.) (The problem arose in MacOS Classic, as seen by Pudge, the cure by Nicholas Clark.) p4raw-id: //depot/perl@16656 --- diff --git a/hv.c b/hv.c index f1d5583..6d8461f 100644 --- a/hv.c +++ b/hv.c @@ -251,7 +251,7 @@ S_hv_fetch_flags(pTHX_ HV *hv, const char *key, I32 klen, I32 lval, int flags) } } - PERL_HASH(hash, (U8*)key, klen); + PERL_HASH(hash, key, klen); /* entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */ entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; @@ -410,7 +410,7 @@ Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval, register U32 hash) } if (!hash) - PERL_HASH(hash, (U8*)key, klen); + PERL_HASH(hash, key, klen); /* entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */ entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; @@ -578,7 +578,7 @@ Perl_hv_store_flags(pTHX_ HV *hv, const char *key, I32 klen, SV *val, HvHASKFLAGS_on((SV*)hv); if (!hash) - PERL_HASH(hash, (U8*)key, klen); + PERL_HASH(hash, key, klen); if (!xhv->xhv_array /* !HvARRAY(hv) */) Newz(505, xhv->xhv_array /* HvARRAY(hv) */, @@ -738,7 +738,7 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, U32 hash) } if (!hash) - PERL_HASH(hash, (U8*)key, klen); + PERL_HASH(hash, key, klen); if (!xhv->xhv_array /* !HvARRAY(hv) */) Newz(505, xhv->xhv_array /* HvARRAY(hv) */, @@ -882,7 +882,7 @@ Perl_hv_delete(pTHX_ HV *hv, const char *key, I32 klen, I32 flags) k_flags |= HVhek_FREEKEY; } - PERL_HASH(hash, (U8*)key, klen); + PERL_HASH(hash, key, klen); /* oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */ oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; @@ -1038,7 +1038,7 @@ Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash) } if (!hash) - PERL_HASH(hash, (U8*)key, klen); + PERL_HASH(hash, key, klen); /* oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */ oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; @@ -1185,7 +1185,7 @@ Perl_hv_exists(pTHX_ HV *hv, const char *key, I32 klen) k_flags |= HVhek_FREEKEY; } - PERL_HASH(hash, (U8*)key, klen); + PERL_HASH(hash, key, klen); #ifdef DYNAMIC_ENV_FETCH if (!xhv->xhv_array /* !HvARRAY(hv) */) entry = Null(HE*); @@ -1290,7 +1290,7 @@ Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash) k_flags |= HVhek_FREEKEY; } if (!hash) - PERL_HASH(hash, (U8*)key, klen); + PERL_HASH(hash, key, klen); #ifdef DYNAMIC_ENV_FETCH if (!xhv->xhv_array /* !HvARRAY(hv) */) entry = Null(HE*); diff --git a/hv.h b/hv.h index 4979fdd..16b1482 100644 --- a/hv.h +++ b/hv.h @@ -47,12 +47,19 @@ struct xpvhv { }; /* hash a key */ -/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins */ -/* from requirements by Colin Plumb. */ -/* (http://burtleburtle.net/bob/hash/doobs.html) */ +/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins + * from requirements by Colin Plumb. + * (http://burtleburtle.net/bob/hash/doobs.html) */ +/* The use of a temporary pointer and the casting games + * is needed to serve the dual purposes of + * (a) the hashed data being interpreted as "unsigned char" (new since 5.8, + * a "char" can be either signed or signed, depending on the compiler) + * (b) catering for old code that uses a "char" + */ #define PERL_HASH(hash,str,len) \ STMT_START { \ - register const unsigned char *s_PeRlHaSh = str; \ + register const char *s_PeRlHaSh_tmp = str; \ + register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \ register I32 i_PeRlHaSh = len; \ register U32 hash_PeRlHaSh = 0; \ while (i_PeRlHaSh--) { \ diff --git a/op.c b/op.c index d63b2a3..8ee4e31 100644 --- a/op.c +++ b/op.c @@ -2011,7 +2011,7 @@ S_apply_attrs_my(pTHX_ HV *stash, OP *target, OP *attrs, OP **imopsp) meth = newSVpvn("import", 6); (void)SvUPGRADE(meth, SVt_PVIV); (void)SvIOK_on(meth); - PERL_HASH(SvUVX(meth), (U8*)SvPVX(meth), SvCUR(meth)); + PERL_HASH(SvUVX(meth), SvPVX(meth), SvCUR(meth)); imop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL|OPf_WANT_VOID, append_elem(OP_LIST, prepend_elem(OP_LIST, pack, list(arg)), @@ -3402,7 +3402,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *id, OP *arg) meth = newSVpvn("VERSION",7); sv_upgrade(meth, SVt_PVIV); (void)SvIOK_on(meth); - PERL_HASH(SvUVX(meth), (U8*)SvPVX(meth), SvCUR(meth)); + PERL_HASH(SvUVX(meth), SvPVX(meth), SvCUR(meth)); veop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL, append_elem(OP_LIST, prepend_elem(OP_LIST, pack, list(version)), @@ -3426,7 +3426,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *id, OP *arg) meth = aver ? newSVpvn("import",6) : newSVpvn("unimport", 8);; (void)SvUPGRADE(meth, SVt_PVIV); (void)SvIOK_on(meth); - PERL_HASH(SvUVX(meth), (U8*)SvPVX(meth), SvCUR(meth)); + PERL_HASH(SvUVX(meth), SvPVX(meth), SvCUR(meth)); imop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL, append_elem(OP_LIST, prepend_elem(OP_LIST, pack, list(arg)), diff --git a/sv.c b/sv.c index 5992a69..ff53fae 100644 --- a/sv.c +++ b/sv.c @@ -6338,7 +6338,7 @@ Perl_newSVpvn_share(pTHX_ const char *src, I32 len, U32 hash) len = tmplen; } if (!hash) - PERL_HASH(hash, (U8*)src, len); + PERL_HASH(hash, src, len); new_SV(sv); sv_upgrade(sv, SVt_PVIV); SvPVX(sv) = sharepvn(src, is_utf8?-len:len, hash); diff --git a/vms/vms.c b/vms/vms.c index a546076..146d8a6 100644 --- a/vms/vms.c +++ b/vms/vms.c @@ -587,7 +587,7 @@ prime_env_iter(void) Perl_warner(aTHX_ packWARN(WARN_INTERNAL),"Ill-formed message in prime_env_iter: |%s|",buf); continue; } - PERL_HASH(hash,(U8*)key,keylen); + PERL_HASH(hash,key,keylen); sv = newSVpvn(cp2,cp1 - cp2 + 1); SvTAINTED_on(sv); hv_store(envhv,key,keylen,sv,hash);