-/* $Header: str.c,v 3.0.1.5 90/02/28 18:30:38 lwall Locked $
+/* $Header: str.c,v 3.0.1.8 90/08/09 05:22:18 lwall Locked $
*
* Copyright (c) 1989, Larry Wall
*
* as specified in the README file that comes with the perl 3.0 kit.
*
* $Log: str.c,v $
+ * Revision 3.0.1.8 90/08/09 05:22:18 lwall
+ * patch19: the number to string converter wasn't allocating enough space
+ * patch19: tainting didn't work on setgid scripts
+ *
+ * Revision 3.0.1.7 90/03/27 16:24:11 lwall
+ * patch16: strings with prefix chopped off sometimes freed wrong
+ * patch16: taint check blows up on undefined array element
+ *
+ * Revision 3.0.1.6 90/03/12 17:02:14 lwall
+ * patch13: substr as lvalue didn't invalidate old numeric value
+ *
* Revision 3.0.1.5 90/02/28 18:30:38 lwall
* patch9: you may now undef $/ to have no input record separator
* patch9: nested evals clobbered their longjmp environment
char *
str_grow(str,newlen)
register STR *str;
+#ifndef MSDOS
register int newlen;
+#else
+unsigned long newlen;
+#endif
{
register char *s = str->str_ptr;
+#ifdef MSDOS
+ if (newlen >= 0x10000) {
+ fprintf(stderr, "Allocation too large: %lx\n", newlen);
+ exit(1);
+ }
+#endif /* MSDOS */
if (str->str_state == SS_INCR) { /* data before str_ptr? */
str->str_len += str->str_u.str_useful;
str->str_ptr -= str->str_u.str_useful;
register STR *str;
double num;
{
+ if (str->str_pok) {
+ str->str_pok = 0; /* invalidate pointer */
+ if (str->str_state == SS_INCR)
+ Str_Grow(str,0);
+ }
str->str_u.str_nval = num;
str->str_state = SS_NORM;
- str->str_pok = 0; /* invalidate pointer */
str->str_nok = 1; /* validate number */
#ifdef TAINT
str->str_tainted = tainted;
if (!str)
return "";
if (str->str_nok) {
-/* this is a problem on the sun 4... 24 bytes is not always enough and the
- exponent blows away the malloc stack
- PEJ Wed Jan 31 18:41:34 CST 1990
-*/
-#ifdef sun4
STR_GROW(str, 30);
-#else
- STR_GROW(str, 24);
-#endif /* sun 4 */
s = str->str_ptr;
olderrno = errno; /* some Xenix systems wipe out errno here */
#if defined(scs) && defined(ns32000)
return No;
if (dowarn)
warn("Use of uninitialized variable");
-#ifdef sun4
STR_GROW(str, 30);
-#else
- STR_GROW(str, 24);
-#endif
s = str->str_ptr;
}
*s = '\0';
{
if (!str)
return 0.0;
+ if (str->str_state == SS_INCR)
+ Str_Grow(str,0); /* just force copy down */
str->str_state = SS_NORM;
if (str->str_len && str->str_pok)
str->str_u.str_nval = atof(str->str_ptr);
register STR *sstr;
{
#ifdef TAINT
- tainted |= sstr->str_tainted;
+ if (sstr)
+ tainted |= sstr->str_tainted;
#endif
if (sstr == dstr)
return;
else if (sstr->str_nok)
str_numset(dstr,sstr->str_u.str_nval);
else {
+ if (dstr->str_state == SS_INCR)
+ Str_Grow(dstr,0); /* just force copy down */
+
#ifdef STRUCTCOPY
dstr->str_u = sstr->str_u;
#else
str_nset(str,ptr,len)
register STR *str;
register char *ptr;
-register int len;
+register STRLEN len;
{
STR_GROW(str, len + 1);
- (void)bcopy(ptr,str->str_ptr,len);
+ if (ptr)
+ (void)bcopy(ptr,str->str_ptr,len);
str->str_cur = len;
*(str->str_ptr+str->str_cur) = '\0';
str->str_nok = 0; /* invalidate number */
register STR *str;
register char *ptr;
{
- register int len;
+ register STRLEN len;
if (!ptr)
ptr = "";
register STR *str;
register char *ptr;
{
- register int delta;
+ register STRLEN delta;
if (!(str->str_pok))
fatal("str_chop: internal inconsistency");
str_ncat(str,ptr,len)
register STR *str;
register char *ptr;
-register int len;
+register STRLEN len;
{
if (!(str->str_pok))
(void)str_2ptr(str);
register STR *str;
register char *ptr;
{
- register int len;
+ register STRLEN len;
if (!ptr)
return;
char *keeplist;
{
register char *to;
- register int len;
+ register STRLEN len;
if (!from)
return Nullch;
#else
str_new(len)
#endif
-int len;
+STRLEN len;
{
register STR *str;
STAB *stab;
int how;
char *name;
-int namlen;
+STRLEN namlen;
{
if (str->str_magic)
return;
void
str_insert(bigstr,offset,len,little,littlelen)
STR *bigstr;
-int offset;
-int len;
+STRLEN offset;
+STRLEN len;
char *little;
-int littlelen;
+STRLEN littlelen;
{
register char *big;
register char *mid;
register char *bigend;
register int i;
+ bigstr->str_nok = 0;
+ bigstr->str_pok = SP_VALID; /* disable possible screamer */
+
i = littlelen - len;
if (i > 0) { /* string might grow */
STR_GROW(bigstr, bigstr->str_cur + i + 1);
if (midend > bigend)
fatal("panic: str_insert");
- bigstr->str_pok = SP_VALID; /* disable possible screamer */
-
if (mid - big > bigend - midend) { /* faster to shorten from end */
if (littlelen) {
(void)bcopy(little, mid, littlelen);
register STR *nstr;
{
if (str->str_state == SS_INCR)
- str_grow(str,0); /* just force copy down */
+ Str_Grow(str,0); /* just force copy down */
if (nstr->str_state == SS_INCR)
- str_grow(nstr,0);
+ Str_Grow(nstr,0);
if (str->str_ptr)
Safefree(str->str_ptr);
str->str_ptr = nstr->str_ptr;
#endif /* LEAKTEST */
}
+STRLEN
str_len(str)
register STR *str;
{
register STDCHAR *ptr; /* in the innermost loop into registers */
register int newline = record_separator;/* (assuming >= 6 registers) */
int i;
- int bpx;
- int obpx;
+ STRLEN bpx;
+ STRLEN obpx;
register int get_paragraph;
register char *oldbp;
{
register CMD *cmd;
register ARG *arg;
- line_t oldline = line;
+ CMD *oldcurcmd = curcmd;
int retval;
- char *tmps;
str_sset(linestr,str);
in_eval++;
}
#ifdef DEBUGGING
if (debug & 4) {
- tmps = loop_stack[loop_ptr].loop_label;
+ char *tmps = loop_stack[loop_ptr].loop_label;
deb("(Popping label #%d %s)\n",loop_ptr,
tmps ? tmps : "" );
}
#endif
loop_ptr--;
error_count = 0;
+ curcmd = &compiling;
+ curcmd->c_line = oldcurcmd->c_line;
retval = yyparse();
+ curcmd = oldcurcmd;
in_eval--;
if (retval || error_count)
fatal("Invalid component in string or format");
if (cmd->c_type != C_EXPR || cmd->c_next || arg->arg_type != O_LIST)
fatal("panic: error in parselist %d %x %d", cmd->c_type,
cmd->c_next, arg ? arg->arg_type : -1);
- line = oldline;
Safefree(cmd);
return arg;
}
register STR *str;
register char *t;
STR *toparse;
- int len;
+ STRLEN len;
register int brackets;
register char *d;
STAB *stab;
STR *
str_make(s,len)
char *s;
-int len;
+STRLEN len;
{
register STR *str = Str_new(79,0);
return Nullstr;
}
if (old->str_state == SS_INCR && !(old->str_pok & 2))
- str_grow(old,0);
+ Str_Grow(old,0);
if (new->str_ptr)
Safefree(new->str_ptr);
Copy(old,new,1,STR);
if (debug & 2048)
fprintf(stderr,"%s %d %d %d\n",s,tainted,uid, euid);
#endif
- if (tainted && (!euid || euid != uid)) {
+ if (tainted && (!euid || euid != uid || egid != gid)) {
if (!unsafe)
fatal("%s", s);
else if (dowarn)