diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-03-29 05:56:04 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-03-29 05:56:04 +0000 |
commit | 97e6aaca7c7fe2b3d31d2cd94574710318def24d (patch) | |
tree | a23a36e85df875e63e3145f5173842a5b0c5317d | |
parent | 9c5d90b516e665294fa673ca6d9819d7406a7629 (diff) |
dir.c: do not assume NUL terminator
* dir.c (rb_push_glob): do not assume string is NUL terminated
always, shared substring may not in the future.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63034 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | dir.c | 23 |
1 files changed, 13 insertions, 10 deletions
@@ -2534,6 +2534,7 @@ static VALUE rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */ { long offset = 0; + long len; VALUE ary; /* can contain null bytes as separators */ @@ -2546,19 +2547,21 @@ rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */ } ary = rb_ary_new(); - while (offset < RSTRING_LEN(str)) { - char *p, *pend; + while (offset < (len = RSTRING_LEN(str))) { int status; - p = RSTRING_PTR(str) + offset; - status = push_glob(ary, rb_enc_str_new(p, strlen(p), rb_enc_get(str)), + long rest = len - offset; + const char *pbeg = RSTRING_PTR(str), *p = pbeg + offset; + const char *pend = memchr(p, '\0', rest); + if (pend) { + rest = ++pend - p; + offset = pend - pbeg; + } + else { + offset = len; + } + status = push_glob(ary, rb_str_subseq(str, p-pbeg, rest), base, flags); if (status) GLOB_JUMP_TAG(status); - if (offset >= RSTRING_LEN(str)) break; - p += strlen(p) + 1; - pend = RSTRING_PTR(str) + RSTRING_LEN(str); - while (p < pend && !*p) - p++; - offset = p - RSTRING_PTR(str); } return ary; |