Skip to content

Commit

Permalink
Limit max encodings to 256 and raise error
Browse files Browse the repository at this point in the history
Co-authored-by: Jose Narvaez <[email protected]>
  • Loading branch information
thomasmarshall and goyox86 committed Feb 2, 2024
1 parent 90bfaa0 commit 3126bf7
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 0 deletions.
19 changes: 19 additions & 0 deletions spec/ruby/optional/capi/encoding_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -721,4 +721,23 @@
str.bytes.should == [0, 0x24]
end
end

describe "rb_define_dummy_encoding" do
it "defines the dummy encoding" do
@s.rb_define_dummy_encoding("FOO")
enc = Encoding.find("FOO")
enc.should.dummy?
end

it "returns the index of the dummy encoding" do
index = @s.rb_define_dummy_encoding("BAR")
index.should == Encoding.list.size - 1
end

it "raises EncodingError if too many encodings" do
-> {
1_000.times {|i| @s.rb_define_dummy_encoding("R_#{i}") }
}.should raise_error(EncodingError, "too many encoding (> 256)")
end
end
end
5 changes: 5 additions & 0 deletions spec/ruby/optional/capi/ext/encoding_spec.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ static VALUE encoding_spec_rb_enc_left_char_head(VALUE self, VALUE str, VALUE of
return LONG2NUM(result - ptr);
}

static VALUE encoding_spec_rb_define_dummy_encoding(VALUE self, VALUE name) {
return INT2NUM(rb_define_dummy_encoding(RSTRING_PTR(name)));
}

void Init_encoding_spec(void) {
VALUE cls;
native_rb_encoding_pointer = (rb_encoding**) malloc(sizeof(rb_encoding*));
Expand Down Expand Up @@ -382,6 +386,7 @@ void Init_encoding_spec(void) {
rb_define_method(cls, "rb_uv_to_utf8", encoding_spec_rb_uv_to_utf8, 2);
rb_define_method(cls, "ONIGENC_MBC_CASE_FOLD", encoding_spec_ONIGENC_MBC_CASE_FOLD, 1);
rb_define_method(cls, "rb_enc_left_char_head", encoding_spec_rb_enc_left_char_head, 2);
rb_define_method(cls, "rb_define_dummy_encoding", encoding_spec_rb_define_dummy_encoding, 1);
}

#ifdef __cplusplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ public synchronized Object[] getEncodingList() {
return ArrayUtils.copyOf(ENCODING_LIST_BY_ENCODING_INDEX, ENCODING_LIST_BY_ENCODING_INDEX.length);
}

public synchronized int getEncodingListSize() {
return ENCODING_LIST_BY_ENCODING_INDEX.length;
}

@TruffleBoundary
public RubyEncoding getRubyEncoding(String name) {
final String normalizedName = name.toLowerCase(Locale.ENGLISH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ private static RubyEncoding replicate(Node node, String name, RubyEncoding encod

@Primitive(name = "encoding_create_dummy")
public abstract static class DummyEncodingNode extends EncodingCreationNode {
private static int MAX_ENCODINGS = 256;

@Specialization(guards = "strings.isRubyString(nameObject)", limit = "1")
static RubyArray createDummyEncoding(Object nameObject,
Expand All @@ -726,6 +727,12 @@ static RubyArray createDummyEncoding(Object nameObject,

@TruffleBoundary
private static RubyEncoding createDummy(Node node, String name) {
if (getContext(node).getEncodingManager().getEncodingListSize() >= MAX_ENCODINGS) {
throw new RaiseException(
getContext(node),
coreExceptions(node).encodingErrorTooManyEncodings(MAX_ENCODINGS, node));
}

return getContext(node).getEncodingManager().createDummyEncoding(name);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,15 @@ public RubyException encodingError(Object string, RubyEncoding encoding, Node cu
return ExceptionOperations.createRubyException(context, exceptionClass, errorMessage, currentNode, null);
}

@TruffleBoundary
public RubyException encodingErrorTooManyEncodings(int maxSize, Node currentNode) {
RubyClass exceptionClass = context.getCoreLibrary().encodingErrorClass;
String message = StringUtils.format("too many encoding (> %d)", maxSize);
RubyString errorMessage = StringOperations.createUTF8String(context, language, message);

return ExceptionOperations.createRubyException(context, exceptionClass, errorMessage, currentNode, null);
}

@TruffleBoundary
public RubyException encodingCompatibilityErrorIncompatible(RubyEncoding a, RubyEncoding b, Node currentNode) {
return encodingCompatibilityError(
Expand Down

0 comments on commit 3126bf7

Please sign in to comment.