diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2003-06-30 08:36:38 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2003-06-30 08:36:38 +0000 |
commit | 3cb9023dc910d8a9abbd8d44e501f6e492155eb5 (patch) | |
tree | b6e1589a07fc36b3023e7493649f21049543cb91 /perl.c | |
parent | f9cbb277dec3cb2700132dedd25b05ea72cda45a (diff) | |
download | perl-3cb9023dc910d8a9abbd8d44e501f6e492155eb5.tar.gz |
The 'contiguous' test for argv[], envp[] was bogus
since those need not be in memory end-to-end, e.g.
in Tru64 they are aligned by eight. Loosen the test
so that 'contiguousness' is fulfilled if the elements
are within PTRSIZE alignment. This makes Tru64 to pass
the join.t, too.
p4raw-id: //depot/perl@19889
Diffstat (limited to 'perl.c')
-rw-r--r-- | perl.c | 61 |
1 files changed, 39 insertions, 22 deletions
@@ -934,35 +934,52 @@ setuid perl scripts securely.\n"); PL_origargv = argv; { - char *s = PL_origargv[0]; + /* Set PL_origalen be the sum of the contiguous argv[] + * elements plus the size of the env in case that it is + * contiguous with the argv[]. This is used in mg.c:mg_set() + * as the maximum modifiable length of $0. In the worst case + * the area we are able to modify is limited to the size of + * the original argv[0]. + * --jhi */ + char *s; int i; - - s += strlen(s); - /* See if all the arguments are contiguous in memory */ + int mask = + ~(PTRSIZE == 4 ? 3 : PTRSIZE == 8 ? 7 : PTRSIZE == 16 ? 15 : 0); + + /* See if all the arguments are contiguous in memory. + * Note that 'contiguous' is a loose term because some + * platforms align the argv[] and the envp[]. We just check + * that they are within aligned PTRSIZE bytes. As long as no + * system has something bizarre like the argv[] interleaved + * with some other data, we are fine. (Did I just evoke + * Murphy's Law?) --jhi */ + s = PL_origargv[0]; + while (*s) s++; for (i = 1; i < PL_origargc; i++) { - if (PL_origargv[i] == s + 1 -#ifdef OS2 - || PL_origargv[i] == s + 2 -#endif - ) - { - ++s; - s += strlen(s); /* this one is ok too */ + if (PL_origargv[i] > s && + PL_origargv[i] <= + INT2PTR(char *, PTR2UV(s + PTRSIZE) & mask)) { + s = PL_origargv[i]; + while (*s) s++; } else break; } - /* Can we grab env area too to be used as the area for $0 - * (in case we later modify it)? */ - if (PL_origenviron - && (PL_origenviron[0] == s + 1)) - { + /* Can we grab env area too to be used as the area for $0? */ + if (PL_origenviron && + PL_origenviron[0] > s && + PL_origenviron[0] <= + INT2PTR(char *, PTR2UV(s + PTRSIZE) & mask)) { + s = PL_origenviron[0]; + while (*s) s++; my_setenv("NoNe SuCh", Nullch); - /* force copy of environment */ - for (i = 0; PL_origenviron[i]; i++) - if (PL_origenviron[i] == s + 1) { - ++s; - s += strlen(s); + /* Force copy of environment. */ + for (i = 1; PL_origenviron[i]; i++) + if (PL_origenviron[i] > s && + PL_origenviron[i] <= + INT2PTR(char *, PTR2UV(s + PTRSIZE) & mask)) { + s = PL_origenviron[i]; + while (*s) s++; } else break; |