|
30 | 30 | import java.util.ArrayList; |
31 | 31 | import java.util.Arrays; |
32 | 32 | import java.util.Collections; |
| 33 | +import java.util.HashSet; |
33 | 34 | import java.util.Iterator; |
34 | 35 | import java.util.List; |
35 | 36 | import java.util.Map; |
| 37 | +import java.util.Set; |
36 | 38 | import java.util.SortedMap; |
37 | 39 | import java.util.TreeMap; |
| 40 | +import java.util.logging.Logger; |
38 | 41 |
|
39 | 42 | /** |
40 | 43 | * All generated protocol message classes extend this class. This class implements most of the |
|
52 | 55 | public abstract class GeneratedMessage extends AbstractMessage implements Serializable { |
53 | 56 | private static final long serialVersionUID = 1L; |
54 | 57 |
|
| 58 | + private static final Logger logger = Logger.getLogger(GeneratedMessage.class.getName()); |
| 59 | + |
55 | 60 | /** |
56 | 61 | * For testing. Allows a test to disable the optimization that avoids using field builders for |
57 | 62 | * nested messages until they are requested. By disabling this optimization, existing tests can be |
@@ -394,6 +399,59 @@ protected static IntList emptyIntList() { |
394 | 399 | return IntArrayList.emptyList(); |
395 | 400 | } |
396 | 401 |
|
| 402 | + static final String PRE22_GENCODE_SILENCE_PROPERTY = |
| 403 | + "com.google.protobuf.use_unsafe_pre22_gencode"; |
| 404 | + static final String PRE22_GENCODE_ERROR_PROPERTY = |
| 405 | + "com.google.protobuf.error_on_unsafe_pre22_gencode"; |
| 406 | + |
| 407 | + static final String PRE22_GENCODE_VULNERABILITY_MESSAGE = |
| 408 | + "As of 2022/09/29 (release 21.7) makeExtensionsImmutable should not be called from protobuf" |
| 409 | + + " gencode. If you are seeing this message, your gencode is vulnerable to a denial of" |
| 410 | + + " service attack. You should regenerate your code using protobuf 25.6 or later. Use the" |
| 411 | + + " latest version that meets your needs. However, if you understand the risks and wish" |
| 412 | + + " to continue with vulnerable gencode, you can set the system property" |
| 413 | + + " `-Dcom.google.protobuf.use_unsafe_pre22_gencode` on the command line to silence this" |
| 414 | + + " warning. You also can set" |
| 415 | + + " `-Dcom.google.protobuf.error_on_unsafe_pre22_gencode` to throw an error instead. See" |
| 416 | + + " security vulnerability:" |
| 417 | + + " https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-h4h5-3hr4-j3g2"; |
| 418 | + |
| 419 | + protected static final Set<String> loggedPre22TypeNames = |
| 420 | + Collections.synchronizedSet(new HashSet<String>()); |
| 421 | + |
| 422 | + static void warnPre22Gencode(Class<?> messageClass) { |
| 423 | + if (System.getProperty(PRE22_GENCODE_SILENCE_PROPERTY) != null) { |
| 424 | + return; |
| 425 | + } |
| 426 | + String messageName = messageClass.getName(); |
| 427 | + String vulnerabilityMessage = |
| 428 | + "Vulnerable protobuf generated type in use: " |
| 429 | + + messageName |
| 430 | + + "\n" |
| 431 | + + PRE22_GENCODE_VULNERABILITY_MESSAGE; |
| 432 | + |
| 433 | + if (System.getProperty(PRE22_GENCODE_ERROR_PROPERTY) != null) { |
| 434 | + throw new UnsupportedOperationException(vulnerabilityMessage); |
| 435 | + } |
| 436 | + |
| 437 | + if (!loggedPre22TypeNames.add(messageName)) { |
| 438 | + return; |
| 439 | + } |
| 440 | + |
| 441 | + logger.warning(vulnerabilityMessage); |
| 442 | + } |
| 443 | + |
| 444 | + /** |
| 445 | + * This method only exists as a shim for pre-22 gencode. This function is a no-op other than |
| 446 | + * warning or throwing an error for messages that are not extendable. |
| 447 | + * |
| 448 | + * @throws UnsupportedOperationException if the {@link #PRE22_GENCODE_ERROR_PROPERTY} system |
| 449 | + * property is set. |
| 450 | + */ |
| 451 | + protected void makeExtensionsImmutable() { |
| 452 | + warnPre22Gencode(getClass()); |
| 453 | + } |
| 454 | + |
397 | 455 | protected static LongList emptyLongList() { |
398 | 456 | return LongArrayList.emptyList(); |
399 | 457 | } |
@@ -1037,6 +1095,16 @@ public boolean isInitialized() { |
1037 | 1095 | return super.isInitialized() && extensionsAreInitialized(); |
1038 | 1096 | } |
1039 | 1097 |
|
| 1098 | + /** |
| 1099 | + * This method only exists as a shim for pre-22 gencode (see {@link |
| 1100 | + * GeneratedMessage.warnPre22Gencode}. |
| 1101 | + */ |
| 1102 | + @Override |
| 1103 | + protected void makeExtensionsImmutable() { |
| 1104 | + GeneratedMessage.warnPre22Gencode(getClass()); |
| 1105 | + extensions.makeImmutable(); |
| 1106 | + } |
| 1107 | + |
1040 | 1108 | /** |
1041 | 1109 | * Used by subclasses to serialize extensions. Extension ranges may be interleaved with field |
1042 | 1110 | * numbers, but we must write them in canonical (sorted by field number) order. |
|
0 commit comments