Ruby: rename max_recursion_depth to recursion_limit (#9486)

This will help keep the terminology consistent with the other language
implementations.
pull/9488/head
Adam Cozzette 3 years ago committed by GitHub
parent 9748e4c52c
commit d5ef16c6eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      ruby/ext/google/protobuf_c/message.c
  2. 4
      ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java
  3. 38
      ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
  4. 2
      ruby/tests/common_tests.rb
  5. 8
      ruby/tests/encode_decode_test.rb

@ -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 * format) under the interpretration given by this message class's definition
* and returns a message object with the corresponding field values. * and returns a message object with the corresponding field values.
* @param options [Hash] options for the decoder * @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) { static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
VALUE data = argv[0]; VALUE data = argv[0];
@ -975,7 +975,7 @@ static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
rb_raise(rb_eArgError, "Expected hash arguments."); 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) { if (depth != Qnil && TYPE(depth) == T_FIXNUM) {
options |= UPB_DECODE_MAXDEPTH(FIX2INT(depth)); options |= UPB_DECODE_MAXDEPTH(FIX2INT(depth));
@ -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 * Encodes the given message object to its serialized form in protocol buffers
* wire format. * wire format.
* @param options [Hash] options for the encoder * @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) { static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
Message* msg = ruby_to_Message(argv[0]); Message* msg = ruby_to_Message(argv[0]);
@ -1091,7 +1091,7 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
if (TYPE(hash_args) != T_HASH) { if (TYPE(hash_args) != T_HASH) {
rb_raise(rb_eArgError, "Expected hash arguments."); 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) { if (depth != Qnil && TYPE(depth) == T_FIXNUM) {
options |= UPB_DECODE_MAXDEPTH(FIX2INT(depth)); options |= UPB_DECODE_MAXDEPTH(FIX2INT(depth));

@ -389,7 +389,7 @@ public class RubyMap extends RubyObject {
return newMap; 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>(); List<DynamicMessage> list = new ArrayList<DynamicMessage>();
RubyClass rubyClass = (RubyClass) descriptor.msgclass(context); RubyClass rubyClass = (RubyClass) descriptor.msgclass(context);
FieldDescriptor keyField = descriptor.getField("key"); FieldDescriptor keyField = descriptor.getField("key");
@ -398,7 +398,7 @@ public class RubyMap extends RubyObject {
RubyMessage mapMessage = (RubyMessage) rubyClass.newInstance(context, Block.NULL_BLOCK); RubyMessage mapMessage = (RubyMessage) rubyClass.newInstance(context, Block.NULL_BLOCK);
mapMessage.setField(context, keyField, key); mapMessage.setField(context, keyField, key);
mapMessage.setField(context, valueField, table.get(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; return list;
} }

@ -467,7 +467,7 @@ public class RubyMessage extends RubyObject {
* Encodes the given message object to its serialized form in protocol buffers * Encodes the given message object to its serialized form in protocol buffers
* wire format. * wire format.
* @param options [Hash] options for the encoder * @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) @JRubyMethod(required = 1, optional = 1, meta = true)
public static IRubyObject encode(ThreadContext context, IRubyObject recv, IRubyObject[] args) { public static IRubyObject encode(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
@ -475,17 +475,17 @@ public class RubyMessage extends RubyObject {
throw context.runtime.newArgumentError("Tried to encode a " + args[0].getMetaClass() + " message with " + recv); throw context.runtime.newArgumentError("Tried to encode a " + args[0].getMetaClass() + " message with " + recv);
} }
RubyMessage message = (RubyMessage) args[0]; RubyMessage message = (RubyMessage) args[0];
int maxRecursionDepthInt = SINK_MAXIMUM_NESTING; int recursionLimitInt = SINK_MAXIMUM_NESTING;
if (args.length > 1) { if (args.length > 1) {
RubyHash options = (RubyHash) args[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) { if (recursionLimit != null) {
maxRecursionDepthInt = ((RubyNumeric) maxRecursionDepth).getIntValue(); 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()));
} }
/* /*
@ -496,7 +496,7 @@ public class RubyMessage extends RubyObject {
* format) under the interpretation given by this message class's definition * format) under the interpretation given by this message class's definition
* and returns a message object with the corresponding field values. * and returns a message object with the corresponding field values.
* @param options [Hash] options for the decoder * @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) @JRubyMethod(required = 1, optional = 1, meta = true)
public static IRubyObject decode(ThreadContext context, IRubyObject recv, IRubyObject[] args) { public static IRubyObject decode(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
@ -510,9 +510,9 @@ public class RubyMessage extends RubyObject {
throw context.runtime.newArgumentError("Expected hash arguments."); throw context.runtime.newArgumentError("Expected hash arguments.");
} }
IRubyObject maxRecursionDepth = ((RubyHash) args[1]).fastARef(context.runtime.newSymbol("max_recursion_depth")); IRubyObject recursionLimit = ((RubyHash) args[1]).fastARef(context.runtime.newSymbol("recursion_limit"));
if (maxRecursionDepth != null) { if (recursionLimit != null) {
input.setRecursionLimit(((RubyNumeric) maxRecursionDepth).getIntValue()); input.setRecursionLimit(((RubyNumeric) recursionLimit).getIntValue());
} }
} }
@ -664,9 +664,9 @@ public class RubyMessage extends RubyObject {
return ret; return ret;
} }
protected DynamicMessage build(ThreadContext context, int depth, int maxRecursionDepth) { protected DynamicMessage build(ThreadContext context, int depth, int recursionLimit) {
if (depth >= maxRecursionDepth) { if (depth >= recursionLimit) {
throw context.runtime.newRuntimeError("Maximum recursion depth exceeded during encoding."); throw context.runtime.newRuntimeError("Recursion limit exceeded during encoding.");
} }
// Handle the typical case where the fields.keySet contain the fieldDescriptors // Handle the typical case where the fields.keySet contain the fieldDescriptors
@ -676,7 +676,7 @@ public class RubyMessage extends RubyObject {
if (value instanceof RubyMap) { if (value instanceof RubyMap) {
builder.clearField(fieldDescriptor); builder.clearField(fieldDescriptor);
RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context, 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); builder.addRepeatedField(fieldDescriptor, kv);
} }
@ -685,7 +685,7 @@ public class RubyMessage extends RubyObject {
builder.clearField(fieldDescriptor); builder.clearField(fieldDescriptor);
for (int i = 0; i < repeatedField.size(); i++) { 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); /*isDefaultValueForBytes*/ false);
builder.addRepeatedField(fieldDescriptor, item); builder.addRepeatedField(fieldDescriptor, item);
} }
@ -707,7 +707,7 @@ public class RubyMessage extends RubyObject {
fieldDescriptor.getFullName().equals("google.protobuf.FieldDescriptorProto.default_value")) { fieldDescriptor.getFullName().equals("google.protobuf.FieldDescriptorProto.default_value")) {
isDefaultStringForBytes = true; isDefaultStringForBytes = true;
} }
builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth, maxRecursionDepth, isDefaultStringForBytes)); builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth, recursionLimit, isDefaultStringForBytes));
} }
} }
@ -727,7 +727,7 @@ public class RubyMessage extends RubyObject {
builder.clearField(fieldDescriptor); builder.clearField(fieldDescriptor);
RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context, RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context,
fieldDescriptor); 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); builder.addRepeatedField(fieldDescriptor, kv);
} }
} }
@ -839,7 +839,7 @@ public class RubyMessage extends RubyObject {
// convert a ruby object to protobuf type, skip type check since it is checked on the way in // convert a ruby object to protobuf type, skip type check since it is checked on the way in
private Object convert(ThreadContext context, private Object convert(ThreadContext context,
FieldDescriptor fieldDescriptor, FieldDescriptor fieldDescriptor,
IRubyObject value, int depth, int maxRecursionDepth, IRubyObject value, int depth, int recursionLimit,
boolean isDefaultStringForBytes) { boolean isDefaultStringForBytes) {
Object val = null; Object val = null;
switch (fieldDescriptor.getType()) { switch (fieldDescriptor.getType()) {
@ -881,7 +881,7 @@ public class RubyMessage extends RubyObject {
} }
break; break;
case MESSAGE: case MESSAGE:
val = ((RubyMessage) value).build(context, depth + 1, maxRecursionDepth); val = ((RubyMessage) value).build(context, depth + 1, recursionLimit);
break; break;
case ENUM: case ENUM:
EnumDescriptor enumDescriptor = fieldDescriptor.getEnumType(); EnumDescriptor enumDescriptor = fieldDescriptor.getEnumType();

@ -1245,7 +1245,7 @@ module CommonTests
struct = struct_from_ruby(JSON.parse(json)) struct = struct_from_ruby(JSON.parse(json))
assert_equal json, struct.to_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 = Google::Protobuf::Struct.new
struct.fields["foobar"] = Google::Protobuf::Value.new(struct_value: struct) struct.fields["foobar"] = Google::Protobuf::Value.new(struct_value: struct)
Google::Protobuf::Struct.encode(struct) Google::Protobuf::Struct.encode(struct)

@ -119,10 +119,10 @@ class EncodeDecodeTest < Test::Unit::TestCase
assert_match msg.to_json, msg_out.to_json assert_match msg.to_json, msg_out.to_json
assert_raise Google::Protobuf::ParseError do 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 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 assert_match msg.to_json, msg_out.to_json
end end
@ -144,10 +144,10 @@ class EncodeDecodeTest < Test::Unit::TestCase
assert_match msg.to_json, msg_out.to_json assert_match msg.to_json, msg_out.to_json
assert_raise RuntimeError do assert_raise RuntimeError do
A::B::C::TestMessage.encode(msg, { max_recursion_depth: 5 }) A::B::C::TestMessage.encode(msg, { recursion_limit: 5 })
end 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) msg_out = A::B::C::TestMessage.decode(msg_encoded)
assert_match msg.to_json, msg_out.to_json assert_match msg.to_json, msg_out.to_json
end end

Loading…
Cancel
Save