Gigantic descriptors shouldn't overflow the Java string literal size limit.

pull/3335/head
kenton@google.com 16 years ago
parent 445f1023e1
commit 68996fc874
  1. 1
      java/pom.xml
  2. 12
      java/src/main/java/com/google/protobuf/Descriptors.java
  3. 8
      java/src/test/java/com/google/protobuf/DescriptorsTest.java
  4. 3
      src/Makefile.am
  5. 14
      src/google/protobuf/compiler/java/java_file.cc
  6. 1045
      src/google/protobuf/unittest_enormous_descriptor.proto

@ -112,6 +112,7 @@
<arg value="../src/google/protobuf/unittest_lite.proto" />
<arg value="../src/google/protobuf/unittest_import_lite.proto" />
<arg value="../src/google/protobuf/unittest_lite_imports_nonlite.proto" />
<arg value="../src/google/protobuf/unittest_enormous_descriptor.proto" />
</exec>
</tasks>
<testSourceRoot>target/generated-test-sources</testSourceRoot>

@ -244,7 +244,8 @@ public final class Descriptors {
* encoded in protocol buffer wire format.
*/
public static void internalBuildGeneratedFileFrom(
final String descriptorData, final FileDescriptor[] dependencies,
final String[] descriptorDataParts,
final FileDescriptor[] dependencies,
final InternalDescriptorAssigner descriptorAssigner) {
// Hack: We can't embed a raw byte array inside generated Java code
// (at least, not efficiently), but we can embed Strings. So, the
@ -255,9 +256,16 @@ public final class Descriptors {
// serialized form. So, if we convert it to bytes in ISO-8859-1, we
// should get the original bytes that we want.
// descriptorData may contain multiple strings in order to get around the
// Java 64k string literal limit.
StringBuilder descriptorData = new StringBuilder();
for (String part : descriptorDataParts) {
descriptorData.append(part);
}
final byte[] descriptorBytes;
try {
descriptorBytes = descriptorData.getBytes("ISO-8859-1");
descriptorBytes = descriptorData.toString().getBytes("ISO-8859-1");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(
"Standard encoding ISO-8859-1 not supported by JVM.", e);

@ -397,4 +397,12 @@ public class DescriptorsTest extends TestCase {
assertEquals(values1[i].toString(), values2[i].toString());
}
}
public void testEnormousDescriptor() throws Exception {
// The descriptor for this file is larger than 64k, yet it did not cause
// a compiler error due to an over-long string literal.
assertTrue(
UnittestEnormousDescriptor.getDescriptor()
.toProto().getSerializedSize() > 65536);
}
}

@ -186,6 +186,7 @@ protoc_inputs = \
google/protobuf/unittest_lite.proto \
google/protobuf/unittest_import_lite.proto \
google/protobuf/unittest_lite_imports_nonlite.proto \
google/protobuf/unittest_enormous_descriptor.proto \
google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
EXTRA_DIST = \
@ -225,6 +226,8 @@ protoc_outputs = \
google/protobuf/unittest_custom_options.pb.h \
google/protobuf/unittest_lite_imports_nonlite.pb.cc \
google/protobuf/unittest_lite_imports_nonlite.pb.h \
google/protobuf/unittest_enormous_descriptor.pb.cc \
google/protobuf/unittest_enormous_descriptor.pb.h \
google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \
google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h

@ -256,20 +256,28 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) {
"private static com.google.protobuf.Descriptors.FileDescriptor\n"
" descriptor;\n"
"static {\n"
" java.lang.String descriptorData =\n");
" java.lang.String[] descriptorData = {\n");
printer->Indent();
printer->Indent();
// Only write 40 bytes per line.
static const int kBytesPerLine = 40;
for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
if (i > 0) printer->Print(" +\n");
if (i > 0) {
// Every 400 lines, start a new string literal, in order to avoid the
// 64k length limit.
if (i % 400 == 0) {
printer->Print(",\n");
} else {
printer->Print(" +\n");
}
}
printer->Print("\"$data$\"",
"data", CEscape(file_data.substr(i, kBytesPerLine)));
}
printer->Print(";\n");
printer->Outdent();
printer->Print("\n};\n");
// -----------------------------------------------------------------
// Create the InternalDescriptorAssigner.

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save