Skip to content

Commit

Permalink
Merge pull request #683 from casperisfine/encoding-error
Browse files Browse the repository at this point in the history
Raise JSON::GeneratorError instead of Encoding::UndefinedConversionError
  • Loading branch information
byroot authored Nov 5, 2024
2 parents dcd8292 + 1c44851 commit f373b8c
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 11 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 @@ -1036,6 +1036,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 @@ -402,14 +403,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
10 changes: 9 additions & 1 deletion lib/json/pure/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,13 @@ def generate(obj)
# Assumes !@ascii_only, !@script_safe
private def fast_serialize_string(string, buf) # :nodoc:
buf << '"'
string = string.encode(::Encoding::UTF_8) unless string.encoding == ::Encoding::UTF_8
unless string.encoding == ::Encoding::UTF_8
begin
string = string.encode(::Encoding::UTF_8)
rescue Encoding::UndefinedConversionError => error
raise GeneratorError, error.message
end
end
raise GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding?

if /["\\\x0-\x1f]/n.match?(string)
Expand Down Expand Up @@ -557,6 +563,8 @@ def to_json(state = nil, *args)
else
%("#{JSON.utf8_to_json(string, state.script_safe)}")
end
rescue Encoding::UndefinedConversionError => error
raise ::JSON::GeneratorError, error.message
end

# Module that holds the extending methods if, the String module is
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 @@ -477,12 +477,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 f373b8c

Please sign in to comment.