Skip to content

Commit

Permalink
Ruby: rename max_recursion_depth to recursion_limit (#9486)
Browse files Browse the repository at this point in the history
This will help keep the terminology consistent with the other language
implementations.
  • Loading branch information
acozzette committed Feb 9, 2022
1 parent 9748e4c commit d5ef16c
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 30 deletions.
8 changes: 4 additions & 4 deletions ruby/ext/google/protobuf_c/message.c
Expand Up @@ -959,7 +959,7 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
* format) under the interpretration given by this message class's definition
* and returns a message object with the corresponding field values.
* @param options [Hash] options for the decoder
* max_recursion_depth: set to maximum decoding depth for message (default is 64)
* recursion_limit: set to maximum decoding depth for message (default is 64)
*/
static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
VALUE data = argv[0];
Expand All @@ -975,7 +975,7 @@ static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
rb_raise(rb_eArgError, "Expected hash arguments.");
}

VALUE depth = rb_hash_lookup(hash_args, ID2SYM(rb_intern("max_recursion_depth")));
VALUE depth = rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit")));

if (depth != Qnil && TYPE(depth) == T_FIXNUM) {
options |= UPB_DECODE_MAXDEPTH(FIX2INT(depth));
Expand Down Expand Up @@ -1070,7 +1070,7 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
* Encodes the given message object to its serialized form in protocol buffers
* wire format.
* @param options [Hash] options for the encoder
* max_recursion_depth: set to maximum encoding depth for message (default is 64)
* recursion_limit: set to maximum encoding depth for message (default is 64)
*/
static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
Message* msg = ruby_to_Message(argv[0]);
Expand All @@ -1091,7 +1091,7 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
if (TYPE(hash_args) != T_HASH) {
rb_raise(rb_eArgError, "Expected hash arguments.");
}
VALUE depth = rb_hash_lookup(hash_args, ID2SYM(rb_intern("max_recursion_depth")));
VALUE depth = rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit")));

if (depth != Qnil && TYPE(depth) == T_FIXNUM) {
options |= UPB_DECODE_MAXDEPTH(FIX2INT(depth));
Expand Down
4 changes: 2 additions & 2 deletions ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java
Expand Up @@ -389,7 +389,7 @@ protected IRubyObject deepCopy(ThreadContext context) {
return newMap;
}

protected List<DynamicMessage> build(ThreadContext context, RubyDescriptor descriptor, int depth, int maxRecursionDepth) {
protected List<DynamicMessage> build(ThreadContext context, RubyDescriptor descriptor, int depth, int recursionLimit) {
List<DynamicMessage> list = new ArrayList<DynamicMessage>();
RubyClass rubyClass = (RubyClass) descriptor.msgclass(context);
FieldDescriptor keyField = descriptor.getField("key");
Expand All @@ -398,7 +398,7 @@ protected List<DynamicMessage> build(ThreadContext context, RubyDescriptor descr
RubyMessage mapMessage = (RubyMessage) rubyClass.newInstance(context, Block.NULL_BLOCK);
mapMessage.setField(context, keyField, key);
mapMessage.setField(context, valueField, table.get(key));
list.add(mapMessage.build(context, depth + 1, maxRecursionDepth));
list.add(mapMessage.build(context, depth + 1, recursionLimit));
}
return list;
}
Expand Down
38 changes: 19 additions & 19 deletions ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
Expand Up @@ -467,25 +467,25 @@ public static IRubyObject getDescriptor(ThreadContext context, IRubyObject recv)
* Encodes the given message object to its serialized form in protocol buffers
* wire format.
* @param options [Hash] options for the encoder
* max_recursion_depth: set to maximum encoding depth for message (default is 64)
* recursion_limit: set to maximum encoding depth for message (default is 64)
*/
@JRubyMethod(required = 1, optional = 1, meta = true)
public static IRubyObject encode(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
if (recv != args[0].getMetaClass()) {
throw context.runtime.newArgumentError("Tried to encode a " + args[0].getMetaClass() + " message with " + recv);
}
RubyMessage message = (RubyMessage) args[0];
int maxRecursionDepthInt = SINK_MAXIMUM_NESTING;
int recursionLimitInt = SINK_MAXIMUM_NESTING;

if (args.length > 1) {
RubyHash options = (RubyHash) args[1];
IRubyObject maxRecursionDepth = options.fastARef(context.runtime.newSymbol("max_recursion_depth"));
IRubyObject recursionLimit = options.fastARef(context.runtime.newSymbol("recursion_limit"));

if (maxRecursionDepth != null) {
maxRecursionDepthInt = ((RubyNumeric) maxRecursionDepth).getIntValue();
if (recursionLimit != null) {
recursionLimitInt = ((RubyNumeric) recursionLimit).getIntValue();
}
}
return context.runtime.newString(new ByteList(message.build(context, 0, maxRecursionDepthInt).toByteArray()));
return context.runtime.newString(new ByteList(message.build(context, 0, recursionLimitInt).toByteArray()));
}

/*
Expand All @@ -496,7 +496,7 @@ public static IRubyObject encode(ThreadContext context, IRubyObject recv, IRubyO
* format) under the interpretation given by this message class's definition
* and returns a message object with the corresponding field values.
* @param options [Hash] options for the decoder
* max_recursion_depth: set to maximum decoding depth for message (default is 100)
* recursion_limit: set to maximum decoding depth for message (default is 100)
*/
@JRubyMethod(required = 1, optional = 1, meta = true)
public static IRubyObject decode(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
Expand All @@ -510,9 +510,9 @@ public static IRubyObject decode(ThreadContext context, IRubyObject recv, IRubyO
throw context.runtime.newArgumentError("Expected hash arguments.");
}

IRubyObject maxRecursionDepth = ((RubyHash) args[1]).fastARef(context.runtime.newSymbol("max_recursion_depth"));
if (maxRecursionDepth != null) {
input.setRecursionLimit(((RubyNumeric) maxRecursionDepth).getIntValue());
IRubyObject recursionLimit = ((RubyHash) args[1]).fastARef(context.runtime.newSymbol("recursion_limit"));
if (recursionLimit != null) {
input.setRecursionLimit(((RubyNumeric) recursionLimit).getIntValue());
}
}

Expand Down Expand Up @@ -664,9 +664,9 @@ public IRubyObject toHash(ThreadContext context) {
return ret;
}

protected DynamicMessage build(ThreadContext context, int depth, int maxRecursionDepth) {
if (depth >= maxRecursionDepth) {
throw context.runtime.newRuntimeError("Maximum recursion depth exceeded during encoding.");
protected DynamicMessage build(ThreadContext context, int depth, int recursionLimit) {
if (depth >= recursionLimit) {
throw context.runtime.newRuntimeError("Recursion limit exceeded during encoding.");
}

// Handle the typical case where the fields.keySet contain the fieldDescriptors
Expand All @@ -676,7 +676,7 @@ protected DynamicMessage build(ThreadContext context, int depth, int maxRecursio
if (value instanceof RubyMap) {
builder.clearField(fieldDescriptor);
RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context, fieldDescriptor);
for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth, maxRecursionDepth)) {
for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth, recursionLimit)) {
builder.addRepeatedField(fieldDescriptor, kv);
}

Expand All @@ -685,7 +685,7 @@ protected DynamicMessage build(ThreadContext context, int depth, int maxRecursio

builder.clearField(fieldDescriptor);
for (int i = 0; i < repeatedField.size(); i++) {
Object item = convert(context, fieldDescriptor, repeatedField.get(i), depth, maxRecursionDepth,
Object item = convert(context, fieldDescriptor, repeatedField.get(i), depth, recursionLimit,
/*isDefaultValueForBytes*/ false);
builder.addRepeatedField(fieldDescriptor, item);
}
Expand All @@ -707,7 +707,7 @@ protected DynamicMessage build(ThreadContext context, int depth, int maxRecursio
fieldDescriptor.getFullName().equals("google.protobuf.FieldDescriptorProto.default_value")) {
isDefaultStringForBytes = true;
}
builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth, maxRecursionDepth, isDefaultStringForBytes));
builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth, recursionLimit, isDefaultStringForBytes));
}
}

Expand All @@ -727,7 +727,7 @@ protected DynamicMessage build(ThreadContext context, int depth, int maxRecursio
builder.clearField(fieldDescriptor);
RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context,
fieldDescriptor);
for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth, maxRecursionDepth)) {
for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth, recursionLimit)) {
builder.addRepeatedField(fieldDescriptor, kv);
}
}
Expand Down Expand Up @@ -839,7 +839,7 @@ private FieldDescriptor findField(ThreadContext context, IRubyObject fieldName,
// convert a ruby object to protobuf type, skip type check since it is checked on the way in
private Object convert(ThreadContext context,
FieldDescriptor fieldDescriptor,
IRubyObject value, int depth, int maxRecursionDepth,
IRubyObject value, int depth, int recursionLimit,
boolean isDefaultStringForBytes) {
Object val = null;
switch (fieldDescriptor.getType()) {
Expand Down Expand Up @@ -881,7 +881,7 @@ private Object convert(ThreadContext context,
}
break;
case MESSAGE:
val = ((RubyMessage) value).build(context, depth + 1, maxRecursionDepth);
val = ((RubyMessage) value).build(context, depth + 1, recursionLimit);
break;
case ENUM:
EnumDescriptor enumDescriptor = fieldDescriptor.getEnumType();
Expand Down
2 changes: 1 addition & 1 deletion ruby/tests/common_tests.rb
Expand Up @@ -1245,7 +1245,7 @@ def test_deep_json
struct = struct_from_ruby(JSON.parse(json))
assert_equal json, struct.to_json

assert_raise(RuntimeError, "Maximum recursion depth exceeded during encoding") do
assert_raise(RuntimeError, "Recursion limit exceeded during encoding") do
struct = Google::Protobuf::Struct.new
struct.fields["foobar"] = Google::Protobuf::Value.new(struct_value: struct)
Google::Protobuf::Struct.encode(struct)
Expand Down
8 changes: 4 additions & 4 deletions ruby/tests/encode_decode_test.rb
Expand Up @@ -119,10 +119,10 @@ def test_decode_depth_limit
assert_match msg.to_json, msg_out.to_json

assert_raise Google::Protobuf::ParseError do
A::B::C::TestMessage.decode(msg_encoded, { max_recursion_depth: 4 })
A::B::C::TestMessage.decode(msg_encoded, { recursion_limit: 4 })
end

msg_out = A::B::C::TestMessage.decode(msg_encoded, { max_recursion_depth: 5 })
msg_out = A::B::C::TestMessage.decode(msg_encoded, { recursion_limit: 5 })
assert_match msg.to_json, msg_out.to_json
end

Expand All @@ -144,10 +144,10 @@ def test_encode_depth_limit
assert_match msg.to_json, msg_out.to_json

assert_raise RuntimeError do
A::B::C::TestMessage.encode(msg, { max_recursion_depth: 5 })
A::B::C::TestMessage.encode(msg, { recursion_limit: 5 })
end

msg_encoded = A::B::C::TestMessage.encode(msg, { max_recursion_depth: 6 })
msg_encoded = A::B::C::TestMessage.encode(msg, { recursion_limit: 6 })
msg_out = A::B::C::TestMessage.decode(msg_encoded)
assert_match msg.to_json, msg_out.to_json
end
Expand Down

0 comments on commit d5ef16c

Please sign in to comment.