X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=doop.c;h=7086a7bf4d667cfae0d203fa776684308560dc7d;hb=0c395bd7f1dd17c87bc78fb4f230c4c88e22eb4f;hp=0d8538cc3b2d2781b424e5c954d30bd2457f75aa;hpb=85581909df34d9ffca6c85cafeb2595c4cb89ffb;p=p5sagit%2Fp5-mst-13.2.git diff --git a/doop.c b/doop.c index 0d8538c..7086a7b 100644 --- a/doop.c +++ b/doop.c @@ -1,6 +1,6 @@ /* doop.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -18,14 +18,6 @@ #include #endif -#ifdef BUGGY_MSC - #pragma function(memcmp) -#endif /* BUGGY_MSC */ - -#ifdef BUGGY_MSC - #pragma intrinsic(memcmp) -#endif /* BUGGY_MSC */ - I32 do_trans(sv,arg) SV *sv; @@ -157,10 +149,7 @@ register SV **sarg; register char *s; register char *t; register char *f; - bool dolong; -#ifdef HAS_QUAD - bool doquad; -#endif /* HAS_QUAD */ + char dotype; char ch; register char *send; register SV *arg; @@ -189,10 +178,7 @@ register SV **sarg; f = t; *buf = '\0'; xs = buf; -#ifdef HAS_QUAD - doquad = -#endif /* HAS_QUAD */ - dolong = FALSE; + dotype = '\0'; pre = post = 0; for (t++; t < send; t++) { switch (*t) { @@ -212,12 +198,14 @@ register SV **sarg; continue; case 'l': #ifdef HAS_QUAD - if (dolong) { - dolong = FALSE; - doquad = TRUE; - } else + if (dotype == 'l') + dotype = 'q'; + else #endif - dolong = TRUE; + dotype = 'l'; + continue; + case 'h': + dotype = 's'; continue; case 'c': ch = *(++t); @@ -234,38 +222,54 @@ register SV **sarg; } break; case 'D': - dolong = TRUE; + dotype = 'l'; /* FALL THROUGH */ case 'd': + case 'i': ch = *(++t); *t = '\0'; + switch (dotype) { #ifdef HAS_QUAD - if (doquad) - (void)sprintf(buf,s,(Quad_t)SvNV(arg)); - else + case 'q': + /* perl.h says that if quad is available, IV is quad */ + (void)sprintf(xs,f,(Quad_t)SvIV(arg)); + break; #endif - if (dolong) - (void)sprintf(xs,f,(long)SvNV(arg)); - else - (void)sprintf(xs,f,SvIV(arg)); + case 'l': + (void)sprintf(xs,f,(long)SvIV(arg)); + break; + default: + (void)sprintf(xs,f,(int)SvIV(arg)); + break; + case 's': + (void)sprintf(xs,f,(short)SvIV(arg)); + break; + } xlen = strlen(xs); break; case 'X': case 'O': - dolong = TRUE; + dotype = 'l'; /* FALL THROUGH */ case 'x': case 'o': case 'u': ch = *(++t); *t = '\0'; - value = SvNV(arg); + switch (dotype) { #ifdef HAS_QUAD - if (doquad) - (void)sprintf(buf,s,(unsigned Quad_t)value); - else + case 'q': + /* perl.h says that if quad is available, UV is quad */ + (void)sprintf(xs,f,(unsigned Quad_t)SvUV(arg)); + break; #endif - if (dolong) - (void)sprintf(xs,f,U_L(value)); - else - (void)sprintf(xs,f,U_I(value)); + case 'l': + (void)sprintf(xs,f,(unsigned long)SvUV(arg)); + break; + default: + (void)sprintf(xs,f,(unsigned int)SvUV(arg)); + break; + case 's': + (void)sprintf(xs,f,(unsigned short)SvUV(arg)); + break; + } xlen = strlen(xs); break; case 'E': case 'e': case 'f': case 'G': case 'g': @@ -273,6 +277,15 @@ register SV **sarg; *t = '\0'; (void)sprintf(xs,f,SvNV(arg)); xlen = strlen(xs); +#ifdef LC_NUMERIC + /* + * User-defined locales may include arbitrary characters. + * And, unfortunately, some system may alloc the "C" locale + * to be overridden by a malicious user. + */ + if (op->op_type == OP_SPRINTF) + SvTAINTED_on(sv); +#endif /* LC_NUMERIC */ break; case 's': ch = *(++t); @@ -498,7 +511,7 @@ register SV *sv; goto nope; len -= rslen - 1; s -= rslen - 1; - if (memcmp(s, rsptr, rslen)) + if (memNE(s, rsptr, rslen)) goto nope; count += rslen; } @@ -527,19 +540,32 @@ SV *right; register char *dc; STRLEN leftlen; STRLEN rightlen; - register char *lc = SvPV(left, leftlen); - register char *rc = SvPV(right, rightlen); + register char *lc; + register char *rc; register I32 len; I32 lensave; - char *lsave = lc; - char *rsave = rc; + char *lsave; + char *rsave; - dc = SvPV_force(sv,na); + if (sv != left || (optype != OP_BIT_AND && !SvOK(sv) && !SvGMAGICAL(sv))) + sv_setpvn(sv, "", 0); /* avoid undef warning on |= and ^= */ + lsave = lc = SvPV(left, leftlen); + rsave = rc = SvPV(right, rightlen); len = leftlen < rightlen ? leftlen : rightlen; lensave = len; - if (SvCUR(sv) < len) { - dc = SvGROW(sv,len + 1); - (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1); + if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) { + dc = SvPV_force(sv, na); + if (SvCUR(sv) < len) { + dc = SvGROW(sv, len + 1); + (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1); + } + } + else { + I32 needlen = ((optype == OP_BIT_AND) + ? len : (leftlen > rightlen ? leftlen : rightlen)); + Newz(801, dc, needlen + 1, char); + (void)sv_usepvn(sv, dc, needlen); + dc = SvPVX(sv); /* sv_usepvn() calls Renew() */ } SvCUR_set(sv, len); (void)SvPOK_only(sv); @@ -641,6 +667,9 @@ dARGS (void)hv_iterinit(hv); /* always reset iterator regardless */ + if (op->op_private & OPpLEAVE_VOID) + RETURN; + if (GIMME != G_ARRAY) { I32 i; dTARGET;