aboutsummaryrefslogtreecommitdiff
path: root/javanano
diff options
context:
space:
mode:
authorBrian Duff <bduff@google.com>2014-10-03 14:41:43 -0700
committerBrian Duff <bduff@google.com>2015-04-28 11:42:01 -0700
commitec2f2445546b3e63e4102c3541d4330e97cef07e (patch)
treebfdc2b4a644bb18754fee4b2a0170aeaf00ce881 /javanano
parentfe7b5667eb446766a1c2f30c691662a36f3df1f8 (diff)
downloadprotobuf-ec2f2445546b3e63e4102c3541d4330e97cef07e.tar.gz
protobuf-ec2f2445546b3e63e4102c3541d4330e97cef07e.tar.bz2
protobuf-ec2f2445546b3e63e4102c3541d4330e97cef07e.zip
Fix bug with large extension field numbers.
Previously, extensions with field numbers greater than 268435455 would result in a compile time error in generated code that looks something like this: Foo.java:3178: error: integer number too large: 3346754610 3346754610); This is because we were trying to represent the tag number (an unsigned int) using a java int constant, but java int constants are signed, and can't exceed Integer.MAX_VALUE. Fixed by declaring it as a long instead, and casting it down to an int in the implementation. This is safe, because the tag value always fits in 32 bis. Change-Id: If2017bacb4e20af667eaeaf9b65ddc2c30a7709f
Diffstat (limited to 'javanano')
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/Extension.java22
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/Extension.java.rej13
-rw-r--r--javanano/src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto3
3 files changed, 30 insertions, 8 deletions
diff --git a/javanano/src/main/java/com/google/protobuf/nano/Extension.java b/javanano/src/main/java/com/google/protobuf/nano/Extension.java
index c29b030f..2d091f01 100644
--- a/javanano/src/main/java/com/google/protobuf/nano/Extension.java
+++ b/javanano/src/main/java/com/google/protobuf/nano/Extension.java
@@ -74,6 +74,11 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
public static final int TYPE_SINT32 = InternalNano.TYPE_SINT32;
public static final int TYPE_SINT64 = InternalNano.TYPE_SINT64;
+ // Note: these create...() methods take a long for the tag parameter,
+ // because tags are represented as unsigned longs, and these values exist
+ // in generated code as long values. However, they can fit in 32-bits, so
+ // it's safe to cast them to int without loss of precision.
+
/**
* Creates an {@code Extension} of the given message type and tag number.
* Should be used by the generated code only.
@@ -81,8 +86,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
*/
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
- Extension<M, T> createMessageTyped(int type, Class<T> clazz, int tag) {
- return new Extension<M, T>(type, clazz, tag, false);
+ Extension<M, T> createMessageTyped(int type, Class<T> clazz, long tag) {
+ return new Extension<M, T>(type, clazz, (int) tag, false);
}
/**
@@ -92,8 +97,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
*/
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
- Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, int tag) {
- return new Extension<M, T[]>(type, clazz, tag, true);
+ Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, long tag) {
+ return new Extension<M, T[]>(type, clazz, (int) tag, true);
}
/**
@@ -104,8 +109,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @param clazz the boxed Java type of this extension
*/
public static <M extends ExtendableMessageNano<M>, T>
- Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, int tag) {
- return new PrimitiveExtension<M, T>(type, clazz, tag, false, 0, 0);
+ Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, long tag) {
+ return new PrimitiveExtension<M, T>(type, clazz, (int) tag, false, 0, 0);
}
/**
@@ -117,8 +122,9 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
*/
public static <M extends ExtendableMessageNano<M>, T>
Extension<M, T> createRepeatedPrimitiveTyped(
- int type, Class<T> clazz, int tag, int nonPackedTag, int packedTag) {
- return new PrimitiveExtension<M, T>(type, clazz, tag, true, nonPackedTag, packedTag);
+ int type, Class<T> clazz, long tag, long nonPackedTag, long packedTag) {
+ return new PrimitiveExtension<M, T>(type, clazz, (int) tag, true,
+ (int) nonPackedTag, (int) packedTag);
}
/**
diff --git a/javanano/src/main/java/com/google/protobuf/nano/Extension.java.rej b/javanano/src/main/java/com/google/protobuf/nano/Extension.java.rej
new file mode 100644
index 00000000..465495a7
--- /dev/null
+++ b/javanano/src/main/java/com/google/protobuf/nano/Extension.java.rej
@@ -0,0 +1,13 @@
+diff a/javanano/src/main/java/com/google/protobuf/nano/Extension.java b/javanano/src/main/java/com/google/protobuf/nano/Extension.java (rejected hunks)
+@@ -74,6 +74,11 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
+ public static final int TYPE_SINT32 = 17;
+ public static final int TYPE_SINT64 = 18;
+
++ // Note: these create...() methods take a long for the tag parameter,
++ // because tags are represented as unsigned longs, and these values exist
++ // in generated code as long values. However, they can fit in 32-bits, so
++ // it's safe to cast them to int without loss of precision.
++
+ /**
+ * Creates an {@code Extension} of the given message type and tag number.
+ * Should be used by the generated code only.
diff --git a/javanano/src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto b/javanano/src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto
index 2a678a80..d1c5766d 100644
--- a/javanano/src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto
+++ b/javanano/src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto
@@ -21,6 +21,9 @@ message AnotherMessage {
message ContainerMessage {
extend ExtendableMessage {
optional bool another_thing = 100;
+ // The largest permitted field number, per
+ // https://developers.google.com/protocol-buffers/docs/proto#simple
+ optional bool large_field_number = 536870911;
}
}