[#30060] merge YARV — SASADA Koichi <ko1@...>

Hi,

20 messages 2006/12/31
[#30061] Re: merge YARV — SASADA Koichi <ko1@...> 2006/12/31

 ささだです。

[ruby-dev:29999] Re: BUG: Incorrect handling of Ignorecase matching (regex.c of 1.8.5)

From: "きむらこういち" <hogemuta@...>
Date: 2006-12-06 09:57:02 UTC
List: ruby-dev #29999
木村です。

なかださんのパッチが当たっていない状態での回避策を試していて、
修正が不十分であることがわかりました。

なかださんのパッチが当たった状態でも

E:\ruby-stable>ruby185 -ve "p(/(?-i:A)/i =~ 'A')"
ruby 1.8.5 (2006-08-25) [i386-mswin32]
nil

E:\ruby-stable>ruby185 -ve "p(/(?:i(?-i:A))/ =~ 'A')"
ruby 1.8.5 (2006-08-25) [i386-mswin32]
nil

のような例で、マッチすべきなのにマッチに失敗します。
原因は先のものと同根です。

     case exactn:
       if (p[1] == 0xff) {
         if (TRANSLATE_P())
           fastmap[translate[p[2]]] = 2;
         else
           fastmap[p[2]] = 2;
         bufp->options |= RE_OPTIMIZE_BMATCH;
       }
       else if (TRANSLATE_P())
         fastmap[translate[p[1]]] = 1;
       else
         fastmap[p[1]] = 1;
       break;

re_compile_fastmap中の上記の部分で、TRANSLATE_P()によって判定していますが、
その定義は

#define TRANSLATE_P() ((options&RE_OPTION_IGNORECASE) && translate)

となっていて (?:-i) を見つけたところでこのビットを落としてしまうので
translateなしのelse節を通るのですが実際にre_searchでマッチ位置を探すときには
translateありの方を使ってしまうので、先のバグと同じ結果となります。

根本的な修正は修正箇所が複数になるなどの理由で難しいと思いますが、
参考までに試したパッチです。
なかださんのパッチが当たってないソースからの差分です。

とりあえず known bugとしてペンディングしておくかどうかなどはお任せします。


--- regex.c.orig        2006-08-07 12:43:42.000000000 +0900
+++ regex.c     2006-12-06 15:05:27.649250000 +0900
@@ -3104,6 +3104,16 @@ re_compile_fastmap(bufp)
    else
      break;
  }
+
+  if (bufp->options & (RE_OPTION_IGNORECASE|RE_MAY_IGNORECASE)) {
+    int i;
+    for (i = 0; i < (1<<BYTEWIDTH); i++) {
+      char m = fastmap[i];
+      j = translate[i];
+      if (m > fastmap[j]) fastmap[j] = m;
+    }
+  }
+
  FREE_AND_RETURN_VOID(stackb);
 }

-- 
木村浩一
 I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
 mail kbk at kt.rim.or.jp
 web  www.kt.rim.or.jp/~kbk/zakkicho/index.html

In This Thread

Prev Next