diff options
Diffstat (limited to 'java')
14 files changed, 90 insertions, 41 deletions
diff --git a/java/core/pom.xml b/java/core/pom.xml index 14a4bf6c..be0da5ea 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -22,14 +22,17 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> + <scope>test</scope> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> + <scope>test</scope> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymockclassextension</artifactId> + <scope>test</scope> </dependency> </dependencies> diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java index 7639efcf..37180da8 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java @@ -328,8 +328,11 @@ public abstract class AbstractMessage extends AbstractMessageLite.Builder implements Message.Builder { // The compiler produces an error if this is not declared explicitly. + // Method isn't abstract to bypass Java 1.6 compiler issue http://bugs.java.com/view_bug.do?bug_id=6908259 @Override - public abstract BuilderType clone(); + public BuilderType clone() { + throw new UnsupportedOperationException("clone() should be implemented in subclasses."); + } /** TODO(jieluo): Clear it when all subclasses have implemented this method. */ @Override diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java index 14169dc4..239798e4 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -354,9 +354,9 @@ public abstract class CodedInputStream { * * <p>Set the maximum message size. In order to prevent malicious messages from exhausting memory * or causing integer overflows, {@code CodedInputStream} limits how large a message may be. The - * default limit is 64MB. You should set this limit as small as you can without harming your app's - * functionality. Note that size limits only apply when reading from an {@code InputStream}, not - * when constructed around a raw byte array (nor with {@link ByteString#newCodedInput}). + * default limit is {@code Integer.MAX_INT}. You should set this limit as small as you can without + * harming your app's functionality. Note that size limits only apply when reading from an + * {@code InputStream}, not when constructed around a raw byte array. * * <p>If you want to read several messages from a single CodedInputStream, you could call {@link * #resetSizeCounter()} after each one to avoid hitting the size limit. diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java index cea05794..60179e37 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java @@ -854,6 +854,7 @@ public abstract class GeneratedMessage extends AbstractMessage /** Check if a singular extension is present. */ @Override + @SuppressWarnings("unchecked") public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) { Extension<MessageType, Type> extension = checkNotLite(extensionLite); @@ -863,6 +864,7 @@ public abstract class GeneratedMessage extends AbstractMessage /** Get the number of elements in a repeated extension. */ @Override + @SuppressWarnings("unchecked") public final <Type> int getExtensionCount( final ExtensionLite<MessageType, List<Type>> extensionLite) { Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); @@ -2555,6 +2557,7 @@ public abstract class GeneratedMessage extends AbstractMessage } @Override + @SuppressWarnings("unchecked") public Object get(GeneratedMessage message) { List result = new ArrayList(); for (int i = 0; i < getRepeatedCount(message); i++) { @@ -2564,6 +2567,7 @@ public abstract class GeneratedMessage extends AbstractMessage } @Override + @SuppressWarnings("unchecked") public Object get(Builder builder) { List result = new ArrayList(); for (int i = 0; i < getRepeatedCount(builder); i++) { diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java index f885b01e..2d7fd334 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -220,6 +220,7 @@ public abstract class GeneratedMessageLite< } @Override + @SuppressWarnings("unchecked") public final BuilderType toBuilder() { BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER); builder.mergeFrom((MessageType) this); @@ -453,6 +454,7 @@ public abstract class GeneratedMessageLite< */ protected FieldSet<ExtensionDescriptor> extensions = FieldSet.newFieldSet(); + @SuppressWarnings("unchecked") protected final void mergeExtensionFields(final MessageType other) { if (extensions.isImmutable()) { extensions = extensions.clone(); diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java index 2a5d8b50..fd051e75 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java @@ -866,6 +866,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage /** Check if a singular extension is present. */ @Override + @SuppressWarnings("unchecked") public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) { Extension<MessageType, Type> extension = checkNotLite(extensionLite); @@ -875,6 +876,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage /** Get the number of elements in a repeated extension. */ @Override + @SuppressWarnings("unchecked") public final <Type> int getExtensionCount( final ExtensionLite<MessageType, List<Type>> extensionLite) { Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); @@ -2219,6 +2221,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage } @Override + @SuppressWarnings("unchecked") public Object get(GeneratedMessageV3 message) { List result = new ArrayList(); for (int i = 0; i < getRepeatedCount(message); i++) { @@ -2228,6 +2231,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage } @Override + @SuppressWarnings("unchecked") public Object get(Builder builder) { List result = new ArrayList(); for (int i = 0; i < getRepeatedCount(builder); i++) { diff --git a/java/core/src/main/java/com/google/protobuf/MapEntry.java b/java/core/src/main/java/com/google/protobuf/MapEntry.java index 179c3348..7e8e9aad 100644 --- a/java/core/src/main/java/com/google/protobuf/MapEntry.java +++ b/java/core/src/main/java/com/google/protobuf/MapEntry.java @@ -89,6 +89,7 @@ public final class MapEntry<K, V> extends AbstractMessage { } /** Create a MapEntry with the provided key and value. */ + @SuppressWarnings("unchecked") private MapEntry(Metadata metadata, K key, V value) { this.key = key; this.value = value; @@ -435,6 +436,7 @@ public final class MapEntry<K, V> extends AbstractMessage { } @Override + @SuppressWarnings("unchecked") public Builder<K, V> clone() { return new Builder(metadata, key, value); } diff --git a/java/core/src/main/java/com/google/protobuf/MapField.java b/java/core/src/main/java/com/google/protobuf/MapField.java index a6109f98..805defe2 100644 --- a/java/core/src/main/java/com/google/protobuf/MapField.java +++ b/java/core/src/main/java/com/google/protobuf/MapField.java @@ -100,6 +100,7 @@ public class MapField<K, V> implements MutabilityOracle { } @Override + @SuppressWarnings("unchecked") public void convertMessageToKeyAndValue(Message message, Map<K, V> map) { MapEntry<K, V> entry = (MapEntry<K, V>) message; map.put(entry.getKey(), entry.getValue()); diff --git a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java index d2bee2a4..2fc3124d 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java @@ -281,6 +281,7 @@ public class LazyStringArrayListTest extends TestCase { assertGenericListImmutable(byteArrayList, byteArrayList.get(0)); } + @SuppressWarnings("unchecked") private static <T> void assertGenericListImmutable(List<T> list, T value) { try { list.add(value); diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java index d4a18a22..c1bd21db 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java @@ -2602,6 +2602,9 @@ public final class TestUtil { case FOO_CORD: Assert.assertTrue(message.hasFooCord()); break; + case FOO_STRING_PIECE: + Assert.assertTrue(message.hasFooStringPiece()); + break; case FOO_BYTES: Assert.assertTrue(message.hasFooBytes()); break; diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index ac712c94..838700f7 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -35,6 +35,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import com.google.gson.JsonIOException; import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -1067,9 +1068,23 @@ public class JsonFormat { } void merge(Reader json, Message.Builder builder) throws IOException { - JsonReader reader = new JsonReader(json); - reader.setLenient(false); - merge(jsonParser.parse(reader), builder); + try { + JsonReader reader = new JsonReader(json); + reader.setLenient(false); + merge(jsonParser.parse(reader), builder); + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (JsonIOException e) { + // Unwrap IOException. + if (e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } else { + throw new InvalidProtocolBufferException(e.getMessage()); + } + } catch (Exception e) { + // We convert all exceptions from JSON parsing to our own exceptions. + throw new InvalidProtocolBufferException(e.getMessage()); + } } void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException { diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java index 2160e4d5..1d631a2c 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java +++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java @@ -44,6 +44,7 @@ import java.text.SimpleDateFormat; import java.util.Comparator; import java.util.Date; import java.util.GregorianCalendar; +import java.util.Locale; import java.util.TimeZone; /** @@ -83,7 +84,7 @@ public final class Timestamps { }; private static SimpleDateFormat createTimestampFormat() { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); // We use Proleptic Gregorian Calendar (i.e., Gregorian calendar extends // backwards to year one) for timestamp formating. @@ -386,11 +387,11 @@ public final class Timestamps { static String formatNanos(int nanos) { // Determine whether to use 3, 6, or 9 digits for the nano part. if (nanos % NANOS_PER_MILLISECOND == 0) { - return String.format("%1$03d", nanos / NANOS_PER_MILLISECOND); + return String.format(Locale.ENGLISH, "%1$03d", nanos / NANOS_PER_MILLISECOND); } else if (nanos % NANOS_PER_MICROSECOND == 0) { - return String.format("%1$06d", nanos / NANOS_PER_MICROSECOND); + return String.format(Locale.ENGLISH, "%1$06d", nanos / NANOS_PER_MICROSECOND); } else { - return String.format("%1$09d", nanos); + return String.format(Locale.ENGLISH, "%1$09d", nanos); } } } diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index dafd9bb5..de02c117 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -62,13 +62,23 @@ import com.google.protobuf.util.JsonTestProto.TestStruct; import com.google.protobuf.util.JsonTestProto.TestTimestamp; import com.google.protobuf.util.JsonTestProto.TestWrappers; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import junit.framework.TestCase; public class JsonFormatTest extends TestCase { + public JsonFormatTest() { + // Test that locale does not affect JsonFormat. + Locale.setDefault(Locale.forLanguageTag("hi-IN")); + } + private void setAllFields(TestAllTypes.Builder builder) { builder.setOptionalInt32(1234); builder.setOptionalInt64(1234567890123456789L); @@ -1411,4 +1421,34 @@ public class JsonFormatTest extends TestCase { // Expected. } } + + // Test that we are not leaking out JSON exceptions. + public void testJsonException() throws Exception { + InputStream throwingInputStream = new InputStream() { + public int read() throws IOException { + throw new IOException("12345"); + } + }; + InputStreamReader throwingReader = new InputStreamReader(throwingInputStream); + // When the underlying reader throws IOException, JsonFormat should forward + // through this IOException. + try { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + JsonFormat.parser().merge(throwingReader, builder); + fail("Exception is expected."); + } catch (IOException e) { + assertEquals("12345", e.getMessage()); + } + + Reader invalidJsonReader = new StringReader("{ xxx - yyy }"); + // When the JSON parser throws parser exceptions, JsonFormat should turn + // that into InvalidProtocolBufferException. + try { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + JsonFormat.parser().merge(invalidJsonReader, builder); + fail("Exception is expected."); + } catch (InvalidProtocolBufferException e) { + // Expected. + } + } } diff --git a/java/util/src/test/proto/com/google/protobuf/util/json_test.proto b/java/util/src/test/proto/com/google/protobuf/util/json_test.proto index a75338ef..d1248cfb 100644 --- a/java/util/src/test/proto/com/google/protobuf/util/json_test.proto +++ b/java/util/src/test/proto/com/google/protobuf/util/json_test.proto @@ -28,36 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - syntax = "proto3"; package json_test; |