Skip to content

Commit 97a73ef

Browse files
committed
Raise JSON::GeneratorError instead of Encoding::UndefinedConversionError
Followup: ruby#633 That's what was raised historically. You could argue that this new exception is more precise, but I've encountered some real production code that expected the old behavior and that was broken by this change.
1 parent dcd8292 commit 97a73ef

File tree

6 files changed

+33
-11
lines changed

6 files changed

+33
-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

java/src/json/ext/GeneratorMethods.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public static class RbString {
103103
public static IRubyObject to_json(ThreadContext context,
104104
IRubyObject vSelf, IRubyObject[] args) {
105105
return Generator.generateJson(context, (RubyString)vSelf,
106-
Generator.STRING_HANDLER, args);
106+
Generator.STRING_HANDLER, args);
107107
}
108108

109109
/**

lib/json/common.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ def generate(obj, opts = nil)
293293
else
294294
State.generate(obj, opts)
295295
end
296+
rescue Encoding::UndefinedConversionError => error
297+
raise ::JSON::GeneratorError, error.message
296298
end
297299

298300
# :stopdoc:

lib/json/pure/generator.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,8 @@ def to_json(state = nil, *args)
557557
else
558558
%("#{JSON.utf8_to_json(string, state.script_safe)}")
559559
end
560+
rescue Encoding::UndefinedConversionError => error
561+
raise ::JSON::GeneratorError, error.message
560562
end
561563

562564
# 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)