Skip to content

Commit

Permalink
Check encoding compatibility in String#casecmp
Browse files Browse the repository at this point in the history
  • Loading branch information
seven1m committed Jun 7, 2024
1 parent 26acae7 commit a164755
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
8 changes: 2 additions & 6 deletions spec/core/string/casecmp_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
end

it "returns nil if incompatible encodings" do
NATFIXME 'returns nil if incompatible encodings', exception: SpecFailedException do
"あれ".casecmp("れ".encode(Encoding::EUC_JP)).should be_nil
end
"あれ".casecmp("れ".encode(Encoding::EUC_JP)).should be_nil
end

describe "in UTF-8 mode" do
Expand Down Expand Up @@ -145,9 +143,7 @@
end

it "returns nil if incompatible encodings" do
NATFIXME 'returns nil if incompatible encodings', exception: SpecFailedException do
"あれ".casecmp?("れ".encode(Encoding::EUC_JP)).should be_nil
end
"あれ".casecmp?("れ".encode(Encoding::EUC_JP)).should be_nil
end

describe 'for UNICODE characters' do
Expand Down
23 changes: 21 additions & 2 deletions src/string_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2801,19 +2801,38 @@ Value StringObject::casecmp(Env *env, Value other) {
other = StringObject::try_convert(env, other);
if (other->is_nil())
return NilObject::the();

auto other_str = other->as_string_or_raise(env);

if (is_empty() && other_str->is_empty())
return Value::integer(0);

if (!negotiate_compatible_encoding(other_str))
return NilObject::the();

auto str1 = this->downcase(env, "ascii"_s, nullptr);
auto str2 = other->as_string()->downcase(env, "ascii"_s, nullptr);
auto str2 = other_str->downcase(env, "ascii"_s, nullptr);
return str1->cmp(env, Value(str2));
}

Value StringObject::is_casecmp(Env *env, Value other) {
other = StringObject::try_convert(env, other);
if (other->is_nil())
return NilObject::the();

auto other_str = other->as_string_or_raise(env);

if (is_empty() && other_str->is_empty())
return Value::integer(0);

if (!negotiate_compatible_encoding(other_str))
return NilObject::the();

auto str1 = this->downcase(env, "fold"_s, nullptr);
auto str2 = other->as_string()->downcase(env, "fold"_s, nullptr);
auto str2 = other_str->downcase(env, "fold"_s, nullptr);
if (str1->string() == str2->string())
return TrueObject::the();

return FalseObject::the();
}

Expand Down

0 comments on commit a164755

Please sign in to comment.