Project

General

Profile

tsafe_eql.patch

arrtchiu (Matt U), 07/29/2014 03:56 AM

Download (2.48 KB)

View differences:

string.c
2491 2491
}
2492 2492

  
2493 2493
/*
2494
 * call-seq:
2495
 *   str.tsafe_eql?(other)   -> true or false
2496
 *
2497
 * Compares each byte of +str+ against +other+, similarly to String#eql?, but
2498
 * performs the comparison in constant-time.
2499
 *
2500
 * This method is timing-safe if both strings are of equal length.
2501
 */
2502

  
2503
static VALUE
2504
rb_str_tsafe_eql(VALUE str1, VALUE str2)
2505
{
2506
    long len, idx;
2507
    char result;
2508
    const char *buf1, *buf2;
2509

  
2510
    str2 = StringValue(str2);
2511
    len = RSTRING_LEN(str1);
2512

  
2513
    if (RSTRING_LEN(str2) != len) return Qfalse;
2514

  
2515
    buf1 = RSTRING_PTR(str1);
2516
    buf2 = RSTRING_PTR(str2);
2517

  
2518
    result = 0;
2519
    for (idx = 0; idx < len; idx++) {
2520
        result |= buf1[idx] ^ buf2[idx];
2521
    }
2522

  
2523
    if (result == 0) return Qtrue;
2524

  
2525
    return Qfalse;
2526
}
2527

  
2528
/*
2494 2529
 *  call-seq:
2495 2530
 *     string <=> other_string   -> -1, 0, +1 or nil
2496 2531
 *
......
8761 8796
    rb_define_method(rb_cString, "==", rb_str_equal, 1);
8762 8797
    rb_define_method(rb_cString, "===", rb_str_equal, 1);
8763 8798
    rb_define_method(rb_cString, "eql?", rb_str_eql, 1);
8799
    rb_define_method(rb_cString, "tsafe_eql?", rb_str_tsafe_eql, 1);
8764 8800
    rb_define_method(rb_cString, "hash", rb_str_hash_m, 0);
8765 8801
    rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
8766 8802
    rb_define_method(rb_cString, "+", rb_str_plus, 1);
test/ruby/test_string.rb
304 304
    casetest(S("CaT"), S('cAt'), true) # find these in the case.
305 305
  end
306 306

  
307
  def test_TIMING_SAFE_EQUAL # 'tsafe_eql?'
308
    assert_equal(true, S("foo").tsafe_eql?(S("foo")))
309
    assert_equal(false, S("foo").tsafe_eql?(S("foO")))
310
    assert_equal(true, S("f\x00oo").tsafe_eql?(S("f\x00oo")))
311
    assert_equal(false, S("f\x00oo").tsafe_eql?(S("f\x00oO")))
312
  end
313

  
307 314
  def test_capitalize
308 315
    assert_equal(S("Hello"),  S("hello").capitalize)
309 316
    assert_equal(S("Hello"),  S("hELLO").capitalize)
310
-