summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-04-12 10:54:59 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-04-12 10:54:59 +0000
commit207becd9422e53e15fcbbb5a0ab92aae2b87121d (patch)
tree903e87c7f6e08a7b0a802801c159e07be39b859d
parent633479795eba48f0e38d043d29a47a3b9275a265 (diff)
* dir.c (bracket, fnmatch_helper): compare bytewise first, to get
rid of invalid byte sequence. [ruby-dev:38303] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23171 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--dir.c73
-rw-r--r--version.h4
3 files changed, 49 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index 862c9467a3..fe4f424707 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sun Apr 12 19:54:56 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * dir.c (bracket, fnmatch_helper): compare bytewise first, to get
+ rid of invalid byte sequence. [ruby-dev:38303]
+
Sat Apr 11 08:45:57 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* configure.in (Makefile): phony ruby target needs empty command.
diff --git a/dir.c b/dir.c
index 31b752e7f9..14b4872a1d 100644
--- a/dir.c
+++ b/dir.c
@@ -83,37 +83,19 @@ char *strchr(char*,char);
# define Next(p, e, enc) (p + rb_enc_mbclen(p, e, enc))
# define Inc(p, e, enc) ((p) = Next(p, e, enc))
-static int
-char_casecmp(const char *p1, const char *p2, rb_encoding *enc, const int nocase)
-{
- const char *p1end, *p2end;
- unsigned int c1, c2;
-
- if (!*p1 || !*p2) return !!*p1 - !!*p2;
- p1end = p1 + strlen(p1);
- p2end = p2 + strlen(p2);
- c1 = rb_enc_codepoint(p1, p1end, enc);
- c2 = rb_enc_codepoint(p2, p2end, enc);
-
- if (c1 == c2) return 0;
- if (nocase) {
- c1 = rb_enc_toupper(c1, enc);
- c2 = rb_enc_toupper(c2, enc);
- }
- return c1 - c2;
-}
-
static char *
bracket(
const char *p, /* pattern (next to '[') */
+ const char *pend,
const char *s, /* string */
+ const char *send,
int flags,
rb_encoding *enc)
{
- const char *pend = p + strlen(p);
const int nocase = flags & FNM_CASEFOLD;
const int escape = !(flags & FNM_NOESCAPE);
-
+ unsigned int c1, c2;
+ int r;
int ok = 0, not = 0;
if (*p == '!' || *p == '^') {
@@ -127,20 +109,39 @@ bracket(
t1++;
if (!*t1)
return NULL;
- p = Next(t1, pend, enc);
+ p += (r = rb_enc_mbclen(p, pend, enc));
if (p[0] == '-' && p[1] != ']') {
const char *t2 = p + 1;
+ int r2;
if (escape && *t2 == '\\')
t2++;
if (!*t2)
return NULL;
- p = Next(t2, pend, enc);
- if (!ok && char_casecmp(t1, s, enc, nocase) <= 0 && char_casecmp(s, t2, enc, nocase) <= 0)
+ p = t2 + (r2 = rb_enc_mbclen(t2, pend, enc));
+ if (ok) continue;
+ if ((r <= (send-s) && memcmp(t1, s, r) == 0) ||
+ (r2 <= (send-s) && memcmp(t2, s, r) == 0)) {
ok = 1;
+ continue;
+ }
+ c1 = rb_enc_codepoint(s, send, enc);
+ if (nocase) c1 = rb_enc_toupper(c1, enc);
+ c2 = rb_enc_codepoint(t1, pend, enc);
+ if (nocase) c2 = rb_enc_toupper(c2, enc);
+ if (c1 < c2) continue;
+ c2 = rb_enc_codepoint(t2, pend, enc);
+ if (nocase) c2 = rb_enc_toupper(c2, enc);
+ if (c1 > c2) continue;
}
- else
- if (!ok && char_casecmp(t1, s, enc, nocase) == 0)
- ok = 1;
+ else {
+ if (ok) continue;
+ if (r <= (send-s) && memcmp(p, s, r) == 0) continue;
+ if (!nocase) continue;
+ c1 = rb_enc_toupper(rb_enc_codepoint(s, send, enc), enc);
+ c2 = rb_enc_toupper(rb_enc_codepoint(p, pend, enc), enc);
+ if (c1 != c2) continue;
+ }
+ ok = 1;
}
return ok == not ? NULL : (char *)p + 1;
@@ -175,6 +176,8 @@ fnmatch_helper(
const char *s = *scur;
const char *send = s + strlen(s);
+ int r;
+
if (period && *s == '.' && *UNESCAPE(p) != '.') /* leading period */
RETURN(FNM_NOMATCH);
@@ -203,7 +206,7 @@ fnmatch_helper(
const char *t;
if (ISEND(s))
RETURN(FNM_NOMATCH);
- if ((t = bracket(p + 1, s, flags, enc)) != 0) {
+ if ((t = bracket(p + 1, pend, s, send, flags, enc)) != 0) {
p = t;
Inc(s, send, enc);
continue;
@@ -218,9 +221,17 @@ fnmatch_helper(
RETURN(ISEND(p) ? 0 : FNM_NOMATCH);
if (ISEND(p))
goto failed;
- if (char_casecmp(p, s, enc, nocase) != 0)
+ r = rb_enc_mbclen(p, pend, enc);
+ if (r <= (send-s) && memcmp(p, s, r) == 0) {
+ p += r;
+ s += r;
+ continue;
+ }
+ if (!nocase) goto failed;
+ if (rb_enc_toupper(rb_enc_codepoint(p, pend, enc), enc) !=
+ rb_enc_toupper(rb_enc_codepoint(s, send, enc), enc))
goto failed;
- Inc(p, pend, enc);
+ p += r;
Inc(s, send, enc);
continue;
diff --git a/version.h b/version.h
index 03427afa73..44ede70790 100644
--- a/version.h
+++ b/version.h
@@ -1,5 +1,5 @@
#define RUBY_VERSION "1.9.2"
-#define RUBY_RELEASE_DATE "2009-04-11"
+#define RUBY_RELEASE_DATE "2009-04-12"
#define RUBY_PATCHLEVEL -1
#define RUBY_BRANCH_NAME "trunk"
@@ -8,7 +8,7 @@
#define RUBY_VERSION_TEENY 1
#define RUBY_RELEASE_YEAR 2009
#define RUBY_RELEASE_MONTH 4
-#define RUBY_RELEASE_DAY 11
+#define RUBY_RELEASE_DAY 12
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];