From ace0afd9d8231117ac1fa7ccd053348db7f9abf5 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Wed, 4 Sep 2013 09:55:53 +1000 Subject: [PATCH] [perl #117265] do most glob \0 checks in the same place and before we do much processing --- ext/File-Glob/Glob.xs | 68 ++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/ext/File-Glob/Glob.xs b/ext/File-Glob/Glob.xs index 6189b0f..b3705b3 100644 --- a/ext/File-Glob/Glob.xs +++ b/ext/File-Glob/Glob.xs @@ -63,7 +63,7 @@ doglob(pTHX_ const char *pattern, int flags) } static void -iterate(pTHX_ bool(*globber)(pTHX_ AV *entries, SV *patsv)) +iterate(pTHX_ bool(*globber)(pTHX_ AV *entries, const char *pat, STRLEN len, bool is_utf8)) { dSP; dMY_CXT; @@ -80,8 +80,34 @@ iterate(pTHX_ bool(*globber)(pTHX_ AV *entries, SV *patsv)) /* if we're just beginning, do it all first */ if (SvTYPE(entries) != SVt_PVAV) { + const char *pat; + STRLEN len; + bool is_utf8; + + /* glob without args defaults to $_ */ + SvGETMAGIC(patsv); + if ( + !SvOK(patsv) + && (patsv = DEFSV, SvGETMAGIC(patsv), !SvOK(patsv)) + ) { + pat = ""; + len = 0; + is_utf8 = 0; + } + else { + pat = SvPV_nomg(patsv,len); + is_utf8 = !!SvUTF8(patsv); + } + + if (!IS_SAFE_SYSCALL(pat, len, "pattern", "glob")) { + if (gimme != G_ARRAY) + PUSHs(&PL_sv_undef); + PUTBACK; + return; + } + PUTBACK; - on_stack = globber(aTHX_ entries, patsv); + on_stack = globber(aTHX_ entries, pat, len, is_utf8); SPAGAIN; } @@ -111,10 +137,9 @@ iterate(pTHX_ bool(*globber)(pTHX_ AV *entries, SV *patsv)) /* returns true if the items are on the stack already, but only in list context */ static bool -csh_glob(pTHX_ AV *entries, SV *patsv) +csh_glob(pTHX_ AV *entries, const char *pat, STRLEN len, bool is_utf8) { dSP; - const char *pat; AV *patav = NULL; const char *patend; const char *s = NULL; @@ -122,26 +147,13 @@ csh_glob(pTHX_ AV *entries, SV *patsv) SV *word = NULL; int const flags = (int)SvIV(get_sv("File::Glob::DEFAULT_FLAGS", GV_ADD)); - bool is_utf8; - STRLEN len; U32 const gimme = GIMME_V; - /* glob without args defaults to $_ */ - SvGETMAGIC(patsv); - if ( - !SvOK(patsv) - && (patsv = DEFSV, SvGETMAGIC(patsv), !SvOK(patsv)) - ) - pat = "", len = 0, is_utf8 = 0; - else pat = SvPV_nomg(patsv,len), is_utf8 = !!SvUTF8(patsv); patend = pat + len; assert(SvTYPE(entries) != SVt_PVAV); sv_upgrade((SV *)entries, SVt_PVAV); - if (!IS_SAFE_SYSCALL(pat, len, "pattern", "glob")) - return FALSE; - /* extract patterns */ s = pat-1; while (++s < patend) { @@ -179,7 +191,7 @@ csh_glob(pTHX_ AV *entries, SV *patsv) while (isSPACE(*(patend-1))) patend--; /* bsd_glob expects a trailing null, but we cannot mod- ify the original */ - if (patend < SvEND(patsv)) { + if (patend < pat + len) { if (word) sv_setpvn(word, pat, patend-pat); else word = newSVpvn_flags( @@ -285,21 +297,12 @@ csh_glob_iter(pTHX) /* wrapper around doglob that can be passed to the iterator */ static bool -doglob_iter_wrapper(pTHX_ AV *entries, SV *patsv) +doglob_iter_wrapper(pTHX_ AV *entries, const char *pattern, STRLEN len, bool is_utf8) { dSP; - const char *pattern; int const flags = (int)SvIV(get_sv("File::Glob::DEFAULT_FLAGS", GV_ADD)); - SvGETMAGIC(patsv); - if ( - !SvOK(patsv) - && (patsv = DEFSV, SvGETMAGIC(patsv), !SvOK(patsv)) - ) - pattern = ""; - else pattern = SvPV_nomg_nolen(patsv); - PUSHMARK(SP); PUTBACK; doglob(aTHX_ pattern, flags); @@ -342,12 +345,17 @@ GLOB_ERROR() RETVAL void -bsd_glob(pattern,...) - char *pattern +bsd_glob(pattern_sv,...) + SV *pattern_sv PREINIT: int flags = 0; + char *pattern; + STRLEN len; PPCODE: { + pattern = SvPV(pattern_sv, len); + if (!IS_SAFE_SYSCALL(pattern, len, "pattern", "bsd_glob")) + XSRETURN(0); /* allow for optional flags argument */ if (items > 1) { flags = (int) SvIV(ST(1)); -- 1.8.3.1