-
Notifications
You must be signed in to change notification settings - Fork 15.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Poison-pilling mismatched Protobuf Java Full/Lite versions.
PiperOrigin-RevId: 590333552
- Loading branch information
1 parent
807f00b
commit 378bccc
Showing
12 changed files
with
316 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
java/core/src/main/java/com/google/protobuf/RuntimeVersionLite.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
// Protocol Buffers - Google's data interchange format | ||
// Copyright 2008 Google Inc. All rights reserved. | ||
// | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file or at | ||
// https://developers.google.com/open-source/licenses/bsd | ||
|
||
package com.google.protobuf; | ||
|
||
import java.util.logging.Logger; | ||
|
||
/** | ||
* Provides the version of this Protobuf Java runtime, and methods for Protobuf Java gencode to | ||
* validate that versions are compatible. Fields and methods in this class should be only accessed | ||
* by related unit tests and Protobuf Java gencode, and should not be used elsewhere. | ||
*/ | ||
public class RuntimeVersionLite { | ||
|
||
/** Indicates the domain of the Protobuf artifact. */ | ||
public enum RuntimeDomain { | ||
GOOGLE_INTERNAL, | ||
PUBLIC, | ||
} | ||
|
||
// The version of this runtime. | ||
// Automatically updated by Protobuf release process. Do not edit manually. | ||
public static final RuntimeDomain DOMAIN = RuntimeDomain.PUBLIC; | ||
public static final int MAJOR = 3; | ||
public static final int MINOR = 26; | ||
public static final int PATCH = 0; | ||
public static final String SUFFIX = "-dev"; | ||
private static final String VERSION_STRING = versionString(MAJOR, MINOR, PATCH, SUFFIX); | ||
|
||
/** | ||
* Validates that the gencode is in the same domain as the runtime. | ||
* | ||
* <p>This method will be directly called by the google-internal gencode to verify no cross-domain | ||
* usages. | ||
* | ||
* @param gencodeDomain the domain where Protobuf Java code was generated. | ||
* @throws ProtobufRuntimeVersionException if gencodeDomain is not the same as DOMAIN. | ||
*/ | ||
public static void validateProtobufGencodeDomain(RuntimeDomain gencodeDomain) { | ||
// Check the environmental variable, and temporarily disable validation if it's set to true. | ||
String disableFlag = java.lang.System.getenv("TEMORARILY_DISABLE_PROTOBUF_VERSION_CHECK"); | ||
if ((disableFlag != null && disableFlag.equals("true"))) { | ||
return; | ||
} | ||
|
||
if (gencodeDomain != DOMAIN) { | ||
throw new ProtobufRuntimeVersionException( | ||
String.format( | ||
"Mismatched Protobuf Gencode/Runtime domains: gencode %s, runtime %s. Cross-domain" | ||
+ " usage of Protobuf is not supported.", | ||
gencodeDomain, DOMAIN)); | ||
} | ||
} | ||
|
||
/** | ||
* Validates that the lite gencode version is compatible with this lite runtime version according | ||
* to https://protobuf.dev/support/cross-version-runtime-guarantee/. | ||
* | ||
* <p>This method is currently only used by Protobuf Java Lite gencode in OSS. | ||
* | ||
* <p>This method is only for Protobuf Java gencode; do not call it elsewhere. | ||
* | ||
* @param domain the domain where Protobuf Java code was generated. | ||
* @param major the major version of Protobuf Java gencode. | ||
* @param minor the minor version of Protobuf Java gencode. | ||
* @param patch the micro/patch version of Protobuf Java gencode. | ||
* @param suffix the version suffix e.g. "-rc2", "-dev", etc. | ||
* @throws ProtobufRuntimeVersionException if versions are incompatible. | ||
*/ | ||
public static void validateProtobufLiteGencodeVersion( | ||
RuntimeDomain domain, int major, int minor, int patch, String suffix) { | ||
expectProtobufJavaLiteRuntime(); | ||
validateProtobufGencodeVersionImpl(domain, major, minor, patch, suffix); | ||
} | ||
|
||
/** Core method for version validation, regardless of the version fullness. */ | ||
protected static void validateProtobufGencodeVersionImpl( | ||
RuntimeDomain domain, int major, int minor, int patch, String suffix) { | ||
|
||
// Check that version numbers are valid. | ||
if (major < 0 || minor < 0 || patch < 0) { | ||
throw new ProtobufRuntimeVersionException( | ||
"Invalid gencode version: " + versionString(major, minor, patch, suffix)); | ||
} | ||
|
||
validateProtobufGencodeDomain(domain); | ||
|
||
String gencodeVersionString = versionString(major, minor, patch, suffix); | ||
// Check that runtime major version is the same as the gencode major version. | ||
if (major != MAJOR) { | ||
throw new ProtobufRuntimeVersionException( | ||
String.format( | ||
"Mismatched Protobuf Gencode/Runtime major versions: gencode %s, runtime %s. Same" | ||
+ " major version is required.", | ||
gencodeVersionString, VERSION_STRING)); | ||
} | ||
|
||
// Check that runtime version is newer than the gencode version. | ||
if (MINOR < minor || (MINOR == minor && PATCH < patch)) { | ||
throw new ProtobufRuntimeVersionException( | ||
String.format( | ||
"Protobuf Java runtime version cannot be older than the gencode version:" | ||
+ "gencode %s, runtime %s.", | ||
gencodeVersionString, VERSION_STRING)); | ||
} | ||
|
||
// Check that runtime version suffix is the same as the gencode version suffix. | ||
if (!suffix.equals(SUFFIX)) { | ||
throw new ProtobufRuntimeVersionException( | ||
String.format( | ||
"Mismatched Protobuf Gencode/Runtime version suffixes: gencode %s, runtime %s." | ||
+ " Version suffixes must be the same.", | ||
gencodeVersionString, VERSION_STRING)); | ||
} | ||
} | ||
|
||
/** | ||
* A runtime exception to be thrown by the version validator if version is not well defined or | ||
* versions mismatch. | ||
*/ | ||
public static final class ProtobufRuntimeVersionException extends RuntimeException { | ||
public ProtobufRuntimeVersionException(String message) { | ||
super(message); | ||
} | ||
} | ||
|
||
/** Gets the version string given the version segments. */ | ||
private static String versionString(int major, int minor, int patch, String suffix) { | ||
return String.format("%d.%d.%d%s", major, minor, patch, suffix); | ||
} | ||
|
||
/** Checks that the full version runtime is not loaded for the lite gencode. */ | ||
private static void expectProtobufJavaLiteRuntime() { | ||
try { | ||
Class.forName("com.google.protobuf.RuntimeVersion"); | ||
} catch (ClassNotFoundException e) { | ||
return; | ||
} | ||
throw new ProtobufRuntimeVersionException( | ||
"Expected only Protobuf Java Lite runtime, but found Protobuf Java Full runtime."); | ||
} | ||
} |
Oops, something went wrong.