Skip to content

Commit

Permalink
Merge pull request #684 from byroot/v2.7.x-encoding-error
Browse files Browse the repository at this point in the history
[2.7.x] Raise JSON::GeneratorError instead of Encoding::UndefinedConversionError
  • Loading branch information
byroot authored Nov 5, 2024
2 parents e3a3695 + 2f76147 commit 41cadbb
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 12 deletions.
4 changes: 4 additions & 0 deletions ext/json/ext/generator/generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,10 @@ static VALUE generate_json_rescue(VALUE d, VALUE exc)
struct generate_json_data *data = (struct generate_json_data *)d;
fbuffer_free(data->buffer);

if (RBASIC_CLASS(exc) == rb_path2class("Encoding::UndefinedConversionError")) {
exc = rb_exc_new_str(eGeneratorError, rb_funcall(exc, rb_intern("message"), 0));
}

rb_exc_raise(exc);

return Qundef;
Expand Down
20 changes: 13 additions & 7 deletions java/src/json/ext/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.exceptions.RaiseException;

public final class Generator {
private Generator() {
Expand Down Expand Up @@ -390,14 +391,19 @@ void generate(Session session, RubyString object, ByteList buffer) {
RuntimeInfo info = session.getInfo();
RubyString src;

if (object.encoding(session.getContext()) != info.utf8.get()) {
src = (RubyString)object.encode(session.getContext(),
info.utf8.get());
} else {
src = object;
}
try {
if (object.encoding(session.getContext()) != info.utf8.get()) {
src = (RubyString)object.encode(session.getContext(),
info.utf8.get());
} else {
src = object;
}

session.getStringEncoder().encode(src.getByteList(), buffer);
session.getStringEncoder().encode(src.getByteList(), buffer);
} catch (RaiseException re) {
throw Utils.newException(session.getContext(), Utils.M_GENERATOR_ERROR,
re.getMessage());
}
}
};

Expand Down
12 changes: 10 additions & 2 deletions lib/json/pure/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,11 @@ def generate(obj)
if Regexp.method_defined?(:match?)
private def fast_serialize_string(string, buf) # :nodoc:
buf << '"'
string = string.encode(::Encoding::UTF_8) unless string.encoding == ::Encoding::UTF_8
begin
string = string.encode(::Encoding::UTF_8) unless string.encoding == ::Encoding::UTF_8
rescue Encoding::UndefinedConversionError => error
raise GeneratorError, error.message
end
raise GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding?

if /["\\\x0-\x1f]/n.match?(string)
Expand Down Expand Up @@ -536,7 +540,11 @@ def to_json(state = nil, *args)
end
string = self
else
string = encode(::Encoding::UTF_8)
begin
string = encode(::Encoding::UTF_8)
rescue Encoding::UndefinedConversionError => error
raise GeneratorError, error.message
end
end
if state.ascii_only?
%("#{JSON.utf8_to_json_ascii(string, state.script_safe)}")
Expand Down
14 changes: 11 additions & 3 deletions test/json/json_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -470,12 +470,20 @@ def test_invalid_encoding_string
end
assert_includes error.message, "source sequence is illegal/malformed utf-8"

assert_raise(Encoding::UndefinedConversionError) do
assert_raise(JSON::GeneratorError) do
JSON.dump("\x82\xAC\xEF".b)
end

assert_raise(JSON::GeneratorError) do
"\x82\xAC\xEF".b.to_json
end

assert_raise(Encoding::UndefinedConversionError) do
JSON.dump("\x82\xAC\xEF".b)
assert_raise(JSON::GeneratorError) do
["\x82\xAC\xEF".b].to_json
end

assert_raise(JSON::GeneratorError) do
{ foo: "\x82\xAC\xEF".b }.to_json
end
end

Expand Down

0 comments on commit 41cadbb

Please sign in to comment.