PERL_HASH() casting games so that our hashed data is "unsigned
Jarkko Hietaniemi [Fri, 17 May 2002 16:52:15 +0000 (16:52 +0000)]
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

hv.c
hv.h
op.c
sv.c
vms/vms.c

diff --git a/hv.c b/hv.c
index f1d5583..6d8461f 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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 (file)
--- 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);
index a546076..146d8a6 100644 (file)
--- 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);