Feature #10098 » tsafe_eql.patch
| string.c | ||
|---|---|---|
| 
     } 
   | 
||
| 
     /* 
   | 
||
| 
      * call-seq: 
   | 
||
| 
      *   str.tsafe_eql?(other)   -> true or false 
   | 
||
| 
      * 
   | 
||
| 
      * Compares each byte of +str+ against +other+, similarly to String#eql?, but 
   | 
||
| 
      * performs the comparison in constant-time. 
   | 
||
| 
      * 
   | 
||
| 
      * This method is timing-safe if both strings are of equal length. 
   | 
||
| 
      */ 
   | 
||
| 
     static VALUE 
   | 
||
| 
     rb_str_tsafe_eql(VALUE str1, VALUE str2) 
   | 
||
| 
     { 
   | 
||
| 
         long len, idx; 
   | 
||
| 
         char result; 
   | 
||
| 
         const char *buf1, *buf2; 
   | 
||
| 
         str2 = StringValue(str2); 
   | 
||
| 
         len = RSTRING_LEN(str1); 
   | 
||
| 
         if (RSTRING_LEN(str2) != len) return Qfalse; 
   | 
||
| 
         buf1 = RSTRING_PTR(str1); 
   | 
||
| 
         buf2 = RSTRING_PTR(str2); 
   | 
||
| 
         result = 0; 
   | 
||
| 
         for (idx = 0; idx < len; idx++) { 
   | 
||
| 
             result |= buf1[idx] ^ buf2[idx]; 
   | 
||
| 
         } 
   | 
||
| 
         if (result == 0) return Qtrue; 
   | 
||
| 
         return Qfalse; 
   | 
||
| 
     } 
   | 
||
| 
     /* 
   | 
||
| 
      *  call-seq: 
   | 
||
| 
      *     string <=> other_string   -> -1, 0, +1 or nil 
   | 
||
| 
      * 
   | 
||
| ... | ... | |
| 
         rb_define_method(rb_cString, "==", rb_str_equal, 1); 
   | 
||
| 
         rb_define_method(rb_cString, "===", rb_str_equal, 1); 
   | 
||
| 
         rb_define_method(rb_cString, "eql?", rb_str_eql, 1); 
   | 
||
| 
         rb_define_method(rb_cString, "tsafe_eql?", rb_str_tsafe_eql, 1); 
   | 
||
| 
         rb_define_method(rb_cString, "hash", rb_str_hash_m, 0); 
   | 
||
| 
         rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1); 
   | 
||
| 
         rb_define_method(rb_cString, "+", rb_str_plus, 1); 
   | 
||
| test/ruby/test_string.rb | ||
|---|---|---|
| 
         casetest(S("CaT"), S('cAt'), true) # find these in the case. 
   | 
||
| 
       end 
   | 
||
| 
       def test_TIMING_SAFE_EQUAL # 'tsafe_eql?' 
   | 
||
| 
         assert_equal(true, S("foo").tsafe_eql?(S("foo"))) 
   | 
||
| 
         assert_equal(false, S("foo").tsafe_eql?(S("foO"))) 
   | 
||
| 
         assert_equal(true, S("f\x00oo").tsafe_eql?(S("f\x00oo"))) 
   | 
||
| 
         assert_equal(false, S("f\x00oo").tsafe_eql?(S("f\x00oO"))) 
   | 
||
| 
       end 
   | 
||
| 
       def test_capitalize 
   | 
||
| 
         assert_equal(S("Hello"),  S("hello").capitalize) 
   | 
||
| 
         assert_equal(S("Hello"),  S("hELLO").capitalize) 
   | 
||