When constructing the custom JSON enum name map in C# JsonParser, remove the
ContainsKey check so that subsequent aliased enum values overwrite earlier ones,
aligning with the "last match wins" semantics used across C++, Java, PHP, and Python.
PiperOrigin-RevId: 970656172
Custom JSON enum names are defined in descriptor options and looked up
when parsing JSON strings. Instead of performing a linear scan over
Values on each lookup, this change adds a ConcurrentDictionary with
Lazy<Dictionary> to JsonParser to lazily construct and cache the JSON
name to EnumValueDescriptor lookup table per EnumDescriptor on first
access.
Lazy provides thread-safe, lock-free reads on all subsequent accesses.
PiperOrigin-RevId: 963583475
* `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
The goal of this PR is to fix#20371 (closed) #24267 and #24330 and improve the performance of csharp runtime when dealing with deep nested dependencies of .proto files.
- The fix consists in caching the recursive calls for the search of extensions.
- Two identical datasets (nested proto files) are created automatically using Bazel: one to test it with caching enabled, and another one to test it with no caching. Note: the same dataset cannot be used because once it is loaded inside the test, it cannot be unloaded.
- The created datasets have a width of 6 and a depth of 6, enough to showcase the dependency impact and to not impact the testing time for unit tests. This could be configured.
- In the dataset there is only one proto file with a message `Example` whose descriptor is loaded, and by doing so all the dependencies (and sub dependencies) that it has.
- A set of benchmark metrics have been created to evaluate the performance impact before and after the fix.
- The assertion inside the unit test makes sure that when using metrics the number of traversed extensions (dependencies of the dependencies) when using caching, is reduced by a factor of 1000x.
- The second assertion also makes sure that the time used to load the descriptor when using cache is less than the one without using cache.
Closes#20392
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/20392 from fgarciacorona:fix_20371_csharp_deep_dependencies b1353f6fd1
PiperOrigin-RevId: 919713760
This change updates the target frameworks for various C# projects within Protobuf to .NET 8.0, while also maintaining netstandard2.0 for the core library. Support for older frameworks like net45, net50, and netstandard1.1 has been removed.
This updates our project to match our support policy in https://github.com/google/oss-policies-info/blob/main/foundational-dotnet-support-matrix.md which actually dropped support for net45, net50, etc long ago.
PiperOrigin-RevId: 919111969
**Summary**
A near-int.MaxValue length varint overflows PushLimit, corrupting bufferSize to a negative value. ReadRawByte's == guard then never triggers RefillBuffer, causing an out-of-bounds read instead of InvalidProtocolBufferException.TruncatedMessage().
**Fix**
change == to >= in ReadRawByte. Regression tests added for all four affected slow-path variants.
**Tests**
Added `TruncatedMessageWithLargeInnerLengthThrowsInvalidProtocolBufferException` with 4 test cases.
Fixes#26856Closes#26914
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/26914 from pawlos:fix/csharp-readrawbyte-ioob-truncated-message 6bec67cfb2
PiperOrigin-RevId: 914940764
## Summary
`JsonParser.MergeAny()` records the JSON token stream of an Any body and replays it through a fresh `JsonReplayTokenizer` to parse the inner message. The replay tokenizer's `RecursionDepth` was never initialized from the parent tokenizer, so it defaulted to zero — and the recursion-depth check in `JsonParser.Merge()` reads the **tokenizer's** depth field. As a result, every nested `google.protobuf.Any` started at depth zero and the `Settings.RecursionLimit` check never fired.
A pathological JSON document such as
```json
{"@type":"type.googleapis.com/google.protobuf.Any","value":
{"@type":"type.googleapis.com/google.protobuf.Any","value":
{"@type":"type.googleapis.com/google.protobuf.Any","value": ... }}}
```
recurses through `MergeAny -> MergeWellKnownTypeAnyBody -> Merge -> MergeAny -> ...` until the .NET stack is exhausted, raising an uncatchable `StackOverflowException` and terminating the host process.
The pre-existing `// FIXME: Object depth not maintained...` comment in `JsonReplayTokenizer` already acknowledged the gap.
## Prior art
The same bug class has previously been fixed in the sibling language implementations of protobuf:
- **Java** — `mergeAnyMessage` was missing the `currentDepth` increment.
- **Python** — `_ConvertAnyMessage` reached via `methodcaller(...)` bypassed the depth tracking.
The C# `MergeAny` path was overlooked at the time. A C# *array* recursion fix landed previously, but the Any case was not covered.
## Fix
Inherit the parent tokenizer's `RecursionDepth` when constructing a `JsonReplayTokenizer`, so that `JsonParser.Merge()`'s existing limit check applies across the replay boundary.
```csharp
internal JsonReplayTokenizer(IList<JsonToken> tokens, JsonTokenizer nextTokenizer)
{
this.tokens = tokens;
this.nextTokenizer = nextTokenizer;
this.RecursionDepth = nextTokenizer.RecursionDepth;
}
```
## Tests
Added `JsonParserTest.MaliciousRecursionOfAnyInAny`, mirroring the existing `MaliciousRecursionOfObjectsInValue` / `MaliciousRecursionOfArraysInValue` regression tests:
- Builds a 100-deep Any-of-Any document.
- A parser with a generous limit parses it without exception.
- A parser with an insufficient limit throws `InvalidProtocolBufferException` (rather than overflowing the stack).
Without the fix, the second assertion either spins past the configured limit (because each replay tokenizer resets depth to zero) or terminates the test runner with `StackOverflowException`.
Closes#26835
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/26835 from MindflareX:fix/csharp-any-recursion-depth 8d5f5792a0
PiperOrigin-RevId: 904564398
Change a verbatim string literal `@""` to an interpolated string `$""` in `Timestamp.ToDateTime()` exception message.
Resolves#26006.
Closes#26341
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/26341 from tyulpan:fix-csharp-timestamp-exception-message e102d1276a
PiperOrigin-RevId: 903792535
### Description
This PR fixes the issue where an unused `_hasBits` field is allocated in the generated C# code when the number of presence bits is an exact multiple of 32.
**Changes:**
- Updated the `has_bit_field_count_` calculation in `MessageGenerator` to use the formula: `(presence_bit_count + 31) / 32`.
- This ensures that exactly 1 `int32` is allocated for 32 fields, 2 for 64 fields, etc., instead of over-allocating.
**Testing:**
- Added `TestPresenceBits` to `unittest_issues.proto` which includes exactly 32 optional fields.
- Added a unit test in `Proto3OptionalTest.cs` to assert that exactly one `_hasBits0` field is generated via reflection.
Fixes#26391Closes#26455
PiperOrigin-RevId: 885948073