Skip to content

Commit f373b8c

Browse files
authored
Merge pull request #683 from casperisfine/encoding-error
Raise JSON::GeneratorError instead of Encoding::UndefinedConversionError
2 parents dcd8292 + 1c44851 commit f373b8c

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

ext/json/ext/generator/generator.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,10 @@ static VALUE generate_json_rescue(VALUE d, VALUE exc)
10361036
struct generate_json_data *data = (struct generate_json_data *)d;
10371037
fbuffer_free(data->buffer);
10381038

1039+
if (RBASIC_CLASS(exc) == rb_path2class("Encoding::UndefinedConversionError")) {
1040+
exc = rb_exc_new_str(eGeneratorError, rb_funcall(exc, rb_intern("message"), 0));
1041+
}
1042+
10391043
rb_exc_raise(exc);
10401044

10411045
return Qundef;

java/src/json/ext/Generator.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.jruby.runtime.ThreadContext;
1818
import org.jruby.runtime.builtin.IRubyObject;
1919
import org.jruby.util.ByteList;
20+
import org.jruby.exceptions.RaiseException;
2021

2122
public final class Generator {
2223
private Generator() {
@@ -402,14 +403,19 @@ void generate(Session session, RubyString object, ByteList buffer) {
402403
RuntimeInfo info = session.getInfo();
403404
RubyString src;
404405

405-
if (object.encoding(session.getContext()) != info.utf8.get()) {
406-
src = (RubyString)object.encode(session.getContext(),
407-
info.utf8.get());
408-
} else {
409-
src = object;
410-
}
406+
try {
407+
if (object.encoding(session.getContext()) != info.utf8.get()) {
408+
src = (RubyString)object.encode(session.getContext(),
409+
info.utf8.get());
410+
} else {
411+
src = object;
412+
}
411413

412-
session.getStringEncoder().encode(src.getByteList(), buffer);
414+
session.getStringEncoder().encode(src.getByteList(), buffer);
415+
} catch (RaiseException re) {
416+
throw Utils.newException(session.getContext(), Utils.M_GENERATOR_ERROR,
417+
re.getMessage());
418+
}
413419
}
414420
};
415421

lib/json/pure/generator.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,13 @@ def generate(obj)
354354
# Assumes !@ascii_only, !@script_safe
355355
private def fast_serialize_string(string, buf) # :nodoc:
356356
buf << '"'
357-
string = string.encode(::Encoding::UTF_8) unless string.encoding == ::Encoding::UTF_8
357+
unless string.encoding == ::Encoding::UTF_8
358+
begin
359+
string = string.encode(::Encoding::UTF_8)
360+
rescue Encoding::UndefinedConversionError => error
361+
raise GeneratorError, error.message
362+
end
363+
end
358364
raise GeneratorError, "source sequence is illegal/malformed utf-8" unless string.valid_encoding?
359365

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

562570
# Module that holds the extending methods if, the String module is

test/json/json_generator_test.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,12 +477,20 @@ def test_invalid_encoding_string
477477
end
478478
assert_includes error.message, "source sequence is illegal/malformed utf-8"
479479

480-
assert_raise(Encoding::UndefinedConversionError) do
480+
assert_raise(JSON::GeneratorError) do
481+
JSON.dump("\x82\xAC\xEF".b)
482+
end
483+
484+
assert_raise(JSON::GeneratorError) do
481485
"\x82\xAC\xEF".b.to_json
482486
end
483487

484-
assert_raise(Encoding::UndefinedConversionError) do
485-
JSON.dump("\x82\xAC\xEF".b)
488+
assert_raise(JSON::GeneratorError) do
489+
["\x82\xAC\xEF".b].to_json
490+
end
491+
492+
assert_raise(JSON::GeneratorError) do
493+
{ foo: "\x82\xAC\xEF".b }.to_json
486494
end
487495
end
488496

0 commit comments

Comments
 (0)