Commit graph

386 commits

Author SHA1 Message Date
Jason Aragorn Tobias Lunn
713b6a4a24 Add json_options.proto and json_enumvalue_options.proto and/or gencode derived from them to release artifacts
* `protoc`: Included in zips alongside binary
* Java: Generated classes have been added to the Maven `util` artifact
* Ruby: Generated classes have been added to gems
* CMake: `.proto` files are included in installation

PiperOrigin-RevId: 957382561
2026-07-31 16:20:59 -07:00
Tony Liao
d6fc95d0c3 (Second try) Cache the custom JSON names of enum fields upon first lookup.
Benchmark                                                     Mode  Cnt    Score   Error  Units
JsonFormatBenchmark.benchmarkParseJsonCustom                  avgt   50    3.974 ± 0.037  us/op
JsonFormatBenchmark.benchmarkParseJsonDefault                 avgt   50    3.837 ± 0.114  us/op
JsonFormatBenchmark.benchmarkParseJsonUnknown                 avgt   50   33.699 ± 0.256  us/op
JsonFormatBenchmark.benchmarkParseJsonUnknownIgnored          avgt   50   26.216 ± 0.167  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonCustom          avgt   50   20.698 ± 0.457  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonDefault         avgt   50   12.277 ± 0.112  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonUnknownIgnored  avgt   50  364.327 ± 5.504  us/op

Benchmark                                                     Mode  Cnt    Score   Error  Units
JsonFormatBenchmark.benchmarkParseJsonCustom                  avgt   50    5.049 ± 0.057  us/op
JsonFormatBenchmark.benchmarkParseJsonDefault                 avgt   50    3.879 ± 0.072  us/op
JsonFormatBenchmark.benchmarkParseJsonUnknown                 avgt   50   33.157 ± 0.378  us/op
JsonFormatBenchmark.benchmarkParseJsonUnknownIgnored          avgt   50   26.461 ± 0.151  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonCustom          avgt   50   14.664 ± 0.085  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonDefault         avgt   50   12.230 ± 0.101  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonUnknownIgnored  avgt   50  350.246 ± 5.642  us/op

PiperOrigin-RevId: 949670944
2026-07-17 11:26:05 -07:00
Tony Liao
6ef18f6071 Automated rollback of commit 7db08e8f1b.
PiperOrigin-RevId: 949606118
2026-07-17 09:18:44 -07:00
Tony Liao
6155df9cca Additional unit tests verifying ignoringUnknownFields behavior on non-string primitives.
PiperOrigin-RevId: 949064971
2026-07-16 11:07:22 -07:00
Tony Liao
736b238729 New unittest case to validate Java parseJson behavior with 1-element numbers.
PiperOrigin-RevId: 948086203
2026-07-14 21:38:37 -07:00
Tony Liao
e5cfe139bc New unittest case to validate Java parseJson behavior with 1-element arrays.
In Java, it seems like the existing behavior is that we allow
single-element arrays to be parsed into a non-repeated field.

In `public final class JsonArray extends JsonElement implements Iterable<JsonElement>`:
```
  @Override
  public String getAsString() {
    return getAsSingleElement().getAsString();
  }
```

TBH I don't know if this behavior is necessarily _desired_, but here is
a unit test to validate this behavior so that we don't accidentally
break it without intending to.

PiperOrigin-RevId: 947320631
2026-07-13 17:03:49 -07:00
Tony Liao
7db08e8f1b Automated rollback of commit 7a39a4e313.
PiperOrigin-RevId: 947163030
2026-07-13 12:02:07 -07:00
Tony Liao
52e15dc46c Automated rollback of commit 0acf2a471d.
PiperOrigin-RevId: 947052114
2026-07-13 08:21:28 -07:00
Tony Liao
0acf2a471d Cache the custom JSON names of enum fields upon first lookup.
I got the following benchmark runs on my local machine.

Without optimizations:
Benchmark                                                     Mode  Cnt    Score   Error  Units
JsonFormatBenchmark.benchmarkParseJsonCustom                  avgt   50    3.829 ± 0.047  us/op
JsonFormatBenchmark.benchmarkParseJsonDefault                 avgt   50    3.545 ± 0.045  us/op
JsonFormatBenchmark.benchmarkParseJsonUnknown                 avgt   50   31.244 ± 0.307  us/op
JsonFormatBenchmark.benchmarkParseJsonUnknownIgnored          avgt   50   25.471 ± 0.236  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonCustom          avgt   50   20.142 ± 0.103  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonDefault         avgt   50   12.158 ± 0.131  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonUnknownIgnored  avgt   50  352.305 ± 1.611  us/op

With optimizations:
Benchmark                                                     Mode  Cnt    Score   Error  Units
JsonFormatBenchmark.benchmarkParseJsonCustom                  avgt   50    5.002 ± 0.140  us/op
JsonFormatBenchmark.benchmarkParseJsonDefault                 avgt   50    3.893 ± 0.104  us/op
JsonFormatBenchmark.benchmarkParseJsonUnknown                 avgt   50   32.142 ± 0.340  us/op
JsonFormatBenchmark.benchmarkParseJsonUnknownIgnored          avgt   50   25.492 ± 0.281  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonCustom          avgt   50   14.361 ± 0.039  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonDefault         avgt   50   12.053 ± 0.041  us/op
JsonFormatBenchmark.benchmarkParseRepeatedJsonUnknownIgnored  avgt   50  344.182 ± 3.338  us/op

PiperOrigin-RevId: 946047761
2026-07-10 22:08:11 -07:00
Tony Liao
2737dfcc03 Add Java microbenchmark for custom JSON name parsing.
PiperOrigin-RevId: 946046272
2026-07-10 22:04:21 -07:00
Tony Liao
7a39a4e313 json/java: add json_name enumval support
PiperOrigin-RevId: 945901714
2026-07-10 14:51:06 -07:00
Rachel Goldfinger
d5e039a302 Make Timestamps.parse() attempt non-lenient parsing first and warning if this fails.
PiperOrigin-RevId: 944126931
2026-07-07 15:34:12 -07:00
Protobuf Team Bot
3245bdb028 Small optimizations to Java JsonFormat.
- Apply a fast path to Uint64 parse where we try to parse it directly before falling back to the BigDecimal path. This optimization is preexisting on int64 and int32 and uint32 but was missed on Uint64

- Avoid doing out.append(value.subSequence(start, end)) which forces an intermediate copy the string, instead use the out.append(value, start, end)

PiperOrigin-RevId: 937290790
2026-06-24 06:14:18 -07:00
petedmarsh
16b949d98a Json format lienent tests (#27622)
Because JsonFormat uses GSON to parse JSON it has a variety of
leniencies, e.g. allowing keys and values to skip quotes:

```
{hello: world}
```

These behaviours are not part of the ProtoJSON format but they are
behaviours that JsonFormat's parser has. It's possible someone in the
wild depends upon these unknowingly. This adds explicit tests for these
behaviours to make sure that they are not accidentally lost in future.

Closes #27622

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/27622 from petedmarsh:json-format-lienent-tests edebd543cd
PiperOrigin-RevId: 933849754
2026-06-17 12:03:07 -07:00
Protobuf Team Bot
f770097e46 Optimize JsonFormat handling of Struct/Value by casting gencode accessors instead of reflection.
This still retains the reflection path for these types so that it will continue to handle DynamicMessage printing correctly.

PiperOrigin-RevId: 928689274
2026-06-08 11:51:02 -07:00
Protobuf Team Bot
5d01f7bd22 Optimize Java JsonFormat string printing path.
- Use a lookup table for the replacement characters in the ascii range (which is all of the characters that gson escapes except for exactly 2).

- Stream the escapes out ourselves instead of going through gson.toJson(val.toString()) which goes through a lot of heavy gson machinery and makes several copies of the string.

We exactly match the choices that gson made for escapes here to make this an implementation detail change with no observable difference.

PiperOrigin-RevId: 928654085
2026-06-08 10:51:44 -07:00
Protobuf Team Bot
ae1faeedfd Use natural String comparison instead of UTF-8 ByteString comparison for sorting map keys in JsonFormat.
This only changes the sort order in an obscure edge case of map-keys which sort differently in Utf8 and Utf16, meaning a mix of certain characters that are "very high code point but still single char" and "utf16 surrogate pairs".

PiperOrigin-RevId: 922768203
2026-05-28 07:45:14 -07:00
Protobuf Team Bot
61dfcbc7cf Optimize JsonFormat by handling the newline pretty printing better.
PiperOrigin-RevId: 922127998
2026-05-27 07:56:12 -07:00
Protobuf Team Bot
bca685147b Optimize JavaProto JSON string escaping handling.
PiperOrigin-RevId: 921615825
2026-05-26 12:27:10 -07:00
Protobuf Team Bot
40825a1df7 Add option to enable strict JSON parsing in Protobuf Java JsonFormat.
JsonFormat used 'reader.setLenient(false)' to try to get spec JSON behavior out of GSON. However, this mode was still not actually spec JSON. In ~2024 GSON deprecated setLenient(), made that behavior LEGACY_STRICT and added a new level STRICT which is intended to be spec.

Switching unilaterally would be a breaking change for Protobuf: this change just adds the option for users to ask us to use GSON in strict mode. At a later date we will consider flipping the default of this (letting people opt into LEGACY_STRICT if they want to).

PiperOrigin-RevId: 921432331
2026-05-26 06:39:41 -07:00
Mindflare
25e7005814 java: limit numeric string length before BigDecimal parsing (#26908)
## Summary

`BigDecimal(String)` has O(N²) time complexity for N-digit strings on JDK versions before 18 ([JDK-8291514](https://bugs.openjdk.org/browse/JDK-8291514)). Five JSON parser methods — `parseInt32`, `parseInt64`, `parseUint32`, `parseUint64`, and `parseDouble` — pass user-controlled strings directly to `new BigDecimal()` without length validation.

A single JSON numeric value with 1,000,000 digits takes ~13 seconds to parse on JDK 17. This can be used to DoS any service that parses protobuf JSON messages with numeric fields from untrusted input.

### Benchmark (JDK 17, x86-64 Linux)

| Digits | BigDecimal construction time |
|--------|-----|
| 1,000 | 1.8 ms |
| 10,000 | 6.3 ms |
| 100,000 | 133 ms |
| 1,000,000 | **13.1 seconds** |

### Fix

Added a `parseBigDecimal()` helper that rejects strings longer than 1000 characters before constructing `BigDecimal`. This is generous — valid protobuf numeric values never exceed ~350 characters (Double.MAX_VALUE in non-scientific notation is ~309 digits).

### Affected JDK versions

- JDK 8, 11, 17 (all current LTS releases): **Vulnerable** — no built-in string length limit in BigDecimal
- JDK 18+: JDK itself limits BigDecimal string input to 1100 characters by default (JDK-8291514), but the protobuf-level check is still worthwhile as defense-in-depth

### Test

Added `testParserRejectOverlyLongNumericStrings` covering all 5 affected field types.

Closes #26908

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/26908 from MindflareX:fix/java-bigdecimal-length-check a461d0edc6
PiperOrigin-RevId: 904988136
2026-04-24 06:12:50 -07:00
Protobuf Team Bot
34cb33b197 Improve FieldMaskTree behavior in the face of extremely 'long' field paths (ones with a large number of periods)
PiperOrigin-RevId: 898950610
2026-04-13 06:00:20 -07:00
Protobuf Team Bot
94c68efaaa This change does not affect OSS
PiperOrigin-RevId: 876331033
2026-02-27 10:58:09 -08:00
Protobuf Team Bot
365bde3e5f Introduce the ability to print extensions within Any proto by passing an ExtensionRegistry to the Printer.
This method is held back from the public API for now.

PiperOrigin-RevId: 875795864
2026-02-26 10:59:01 -08:00
Protobuf Team Bot
b843769d72 Introduce the ability to print fully qualified extension names and allow passing an ExtensionRegistry to the Parser.
This fixes as issue where extension names were incorrectly printed using their short name which prevents parsing and can lead to ambiguous or duplicate json keys.

This feature is gated by a boolean options printingFullyQualifiedExtensionNames and printingShortExtensionNames for testing. These methods are held back from the public API for now.

PiperOrigin-RevId: 875322649
2026-02-25 13:56:32 -08:00
Protobuf Team Bot
57093a8bd5 Avoid toBigIntegerExact in JsonFormat to avoid degenerate parse behavior in the face of large exponents.
https://github.com/protocolbuffers/protobuf/issues/26032

PiperOrigin-RevId: 874768607
2026-02-24 13:41:47 -08:00
Protobuf Team Bot
bbcc021add Add tests for JsonFormat extension printing.
This change adds base tests case for printing proto2 extensions. It highlights a known issue with parsing extensions as short names and duplicated field names.

PiperOrigin-RevId: 873022900
2026-02-20 12:23:08 -08:00
Mikita Belahlazau
4f076d951f Add metadata annotations for generated Python protobuf symbols.
The pyi generator now includes Kythe annotations for:
*   Extension field constants (e.g., `EXTENSION_FIELD`).
*   Field number constants (e.g., `STRING_FIELD_FIELD_NUMBER`).
*   `Create` methods in generated Stubby client classes.

These annotations allow the Python indexer to link these generated symbols back to their definitions in the `.proto` files.

PiperOrigin-RevId: 852971617
2026-01-06 16:05:56 -08:00
Protobuf Team Bot
ae67a4c195 Internal version update.
PiperOrigin-RevId: 852733884
2026-01-06 05:27:44 -08:00
Sandy Zhang
7beda33399 Clean up dead dist_files targets.
PiperOrigin-RevId: 851412528
2026-01-02 12:19:11 -08:00
Protobuf Team Bot
33b16e8302 Correctly apply JSON recursion limit when parsing an Any-of-Any.
Without this check, an any-of-any-of-any-of-... wouldn't apply the recursion check as intended and cound be arbitrarily deep.

Fixes https://github.com/protocolbuffers/protobuf/issues/25071

PiperOrigin-RevId: 850485466
2025-12-30 12:41:45 -08:00
Protobuf Team Bot
c224a3606f Use Locale.ROOT for all of our formatted error messages.
PiperOrigin-RevId: 846398642
2025-12-18 13:45:47 -08:00
Patrice Arruda
f66ad439e1 refactor(protobuf): remove redundant typecast in Timestamps.normalizedTimestamp (#24671)
Removed unnecessary typecast in the normalizedTimestamp method.

Modified: java/util/src/main/java/com/google/protobuf/util/Timestamps.java

Closes #24671

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/24671 from patricearruda84:remove_redundant_check 6491986c2f
PiperOrigin-RevId: 839898550
2025-12-03 13:47:35 -08:00
Angie Lin
1270e456f4 Fix quote escaping in JsonFormat.print() for FieldMasks.
https://github.com/protocolbuffers/protobuf/issues/24083

PiperOrigin-RevId: 824592626
2025-10-27 11:06:28 -07:00
Protobuf Team Bot
a2b034a9b1 Update to use the forward-looking proper noun "ProtoJSON" to refer to the format which was formerly known as "Proto3 JSON"
PiperOrigin-RevId: 823566944
2025-10-24 09:54:02 -07:00
Protobuf Team Bot
c518f2564e Add Values.of(Map<String, Value> values).
Also update Javadoc to include {@link} syntax and fix typo.

PiperOrigin-RevId: 806318745
2025-09-12 09:43:30 -07:00
Protobuf Team Bot
1932ccbd74 Cut guava dep from the Java Protobuf-Util package.
In a subsequent change we should be able to cut the Guava dep from our Maven package.

https://github.com/protocolbuffers/protobuf/issues/21173

PiperOrigin-RevId: 803086278
2025-09-04 10:40:18 -07:00
Protobuf Team Bot
5768acddf2 Remove protobuf-util usages of guava except annotations.
The annotations will be handled in a subsequent change.

The change to use java.lang.String.split() instead of Guava's Splitter does introduce behavior changes in the case of handling of degenerate/malformed FieldMask paths (paths like `a///`). The handling of malformed paths shape are already arbitrary and inconsistent between the different methods in this file, and callers should not construct such paths. In a future change we may consider validating and throwing an IllegalArgumentException on such malformed paths more explicitly.

https://github.com/protocolbuffers/protobuf/issues/21173

PiperOrigin-RevId: 795126095
2025-08-14 11:34:28 -07:00
Kurt Alfred Kluever
1ae6b6bb9c Validate Duration instances produced by the static factories.
PiperOrigin-RevId: 792163897
2025-08-07 08:11:28 -07:00
Kurt Alfred Kluever
a6dcb2a0e0 Rollback parts of cl/786407535, which accidentally had a behavior change --- it added validity checks to some Duration static factories.
PiperOrigin-RevId: 786681101
2025-07-24 06:34:04 -07:00
Kurt Alfred Kluever
c5b6f75ef0 Inline calls to Guava's Int/LongMath.checkedFoo() (use Math.fooExact() instead).
PiperOrigin-RevId: 786407535
2025-07-23 13:42:32 -07:00
Protobuf Team Bot
1999135e8e Rename maven install back to maven in MODULE.bazel
Fixes https://github.com/protocolbuffers/protobuf/issues/21177

This PR essentially reverts https://github.com/protocolbuffers/protobuf/pull/18641, which claimed

> Since protobuf is not contributing to user's JARs

This is not true since targets like `@com_google_protobuf//:protobuf_java` are meant to be consumed by other projects, therefore protobuf should not use a private maven install namespace. Otherwise, it leads to duplicated maven jars and classpath conflicts. See https://github.com/protocolbuffers/protobuf/issues/21177 and https://github.com/bazel-contrib/rules_jvm_external/issues/916#issuecomment-3045506487

The original warning message caused by multiple modules contributing to `maven` can be suppressed with https://github.com/bazel-contrib/rules_jvm_external/pull/1393, which will be available in rules_jvm_external 6.8.

Closes https://github.com/protocolbuffers/protobuf/pull/22544

PiperOrigin-RevId: 782032198
2025-07-11 10:47:35 -07:00
Protobuf Team Bot
84c5b6314a Add a FieldMaskUtil#trim overload that accepts TrimOptions and allows retaining unset primitive field state.
Existing FieldMaskUtil#trim method behavior remains the same: unset primitive fields specified in the field mask will be explicitly set to their default values after trimming.

PiperOrigin-RevId: 754114689
2025-05-02 13:31:38 -07:00
Protobuf Team Bot
74e9800455 Remove erroneous claim that JsonFormat only supports Proto3 on the JavaDoc of the JsonFormat entry point.
PiperOrigin-RevId: 753603078
2025-05-01 08:40:10 -07:00
Liam Miller-Cushon
fd33160979 Fix an eagerly evaluated preconditions string
This avoids calling `String.format` eagerly, and only formats the error message if the preconditions check fails.

PiperOrigin-RevId: 746652266
2025-04-11 18:22:43 -07:00
Sandy Zhang
f4713e28c6 Add protobuf_maven artifacts to protobuf_maven_dev as well so they can still be referenced correctly using the dev namespace for dev-only targets.
Otherwise, protobuf_maven_dev may provide a different version from a transitive dep, which can result in the wrong version being selected (e.g. when used for bazel-generated maven artifacts).

Also updates protobuf_util_bundle to use protobuf_maven instead of protobuf_maven_dev which is probably more appropriate since its control the deps in the pom.xml file for maven users (though this is functionally the same rn).

Fixes https://github.com/protocolbuffers/protobuf/issues/20710

PiperOrigin-RevId: 738887165
2025-03-20 11:57:29 -07:00
Sandy Zhang
4c7b7a971c Restore custom protobuf maven namespaces to avoid polluting main maven namespace for non-dev dependencies as well.
Fixes #20674

PiperOrigin-RevId: 738081837
2025-03-18 11:31:17 -07:00
Protobuf Team Bot
1df3ddea58 Automated rollback of commit 1d4b6bac6e.
PiperOrigin-RevId: 735780482
2025-03-11 09:22:22 -07:00
Stefan Haustein
7a5905db8e Add a time-j2kt-native target.
PiperOrigin-RevId: 734154761
2025-03-06 08:33:24 -08:00
Mike Kruskal
e045fc60cf Split maven dependencies into dev vs local (#20549)
Closes #20549

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/20549 from protocolbuffers:maven-split a8b30b4f96
PiperOrigin-RevId: 733361548
2025-03-04 09:44:39 -08:00