## Summary
`GPBMessage::parseMessageSet:` reads each MessageSet item's payload bytes into
a separate buffer (because the type-id and payload tags can appear in any
order), then allocates a fresh `GPBCodedInputStream` to decode that buffer. The
fresh stream's `state_.recursionDepth` starts at `0` even when the parent
stream is already several MessageSet items deep, so a chain of nested
MessageSet items grows the native call stack without ever tripping the
documented `kDefaultRecursionLimit` (100). Other parser entry points that
recurse on the same stream (`readGroup:`, `readMessage:`, `readMapEntry:`,
`SkipToEndGroupInternal`) already increment and check `recursionDepth`; the
MessageSet path was the only spot where depth tracking did not cross the stream
boundary.
This change adds a package-private `-initWithData:parentRecursionDepth:`
initializer to `GPBCodedInputStream` that seeds the child stream's depth from
the parent's and runs `CheckRecursionLimit` before parsing begins. To prevent
memory leaks if `CheckRecursionLimit` raises an exception during
initialization, the check is wrapped in a `@try/@catch` block that releases
`self`. `parseMessageSet:` uses that initializer, so depth tracking carries
across the fresh stream. This mirrors the depth-inheritance done by the C++
`ParseContext` spawn helper.
Regression coverage: `testParseMessageSetRecursionDepthCarriedFromParent` in
`GPBWireFormatTests` builds MessageSet-of-MessageSet payloads (each layer is
`MSetMessage -> MSetMessageExtension1.recursive -> MSetMessage -> ...`, adding
2 to the recursion depth per layer). It verifies that 50 layers (depth 100,
`kDefaultRecursionLimit`) parses successfully, while 51 layers (depth 101,
`kDefaultRecursionLimit + 1`) fails with
`GPBCodedInputStreamErrorRecursionDepthExceeded`. Existing
`testErrorRecursionDepthReached` and the rest of `GPBWireFormatTests` continue
to pass unchanged.
## Test plan
- Existing ObjC test suite passes (`GPBWireFormatTests`,
`GPBMessageTests+Serialization`, `GPBCodedInputStreamTests`,
`GPBUnknownFieldsTest`).
- New `testParseMessageSetRecursionDepthCarriedFromParent` passes for both 50
layers (passing at kDefaultRecursionLimit) and 51 layers (failing at
kDefaultRecursionLimit + 1).
Closes#27571
PiperOrigin-RevId: 959041690
When handling deeply nested unknown fields, the `subIndent` string was being over-released in `GPBTextFormatForMessage`, leading to crashes when generating text format for messages with deeply nested unknown fields.
The added test case reproduces this crash by creating a message with unknown fields nested deep enough to cause the indent string to be heap-allocated, and then adding siblings at that depth, triggering the incorrect release.
Removing the redundant `[subIndent release]` resolves the issue.
PiperOrigin-RevId: 895495564
If the class is writing to an NSOutputStream, the buffer must always
be used to batch things up. The tests were accidentally making a zero
length buffer which isn't valid.
Fix the tests to not do this.
Make the core code assert in debug to ensure the invariant can't be
broken.
PiperOrigin-RevId: 817153199
Replaces the string literal initialization to an explicit character array initialization to avoid the implicit null terminator. The string "\1\0\2\3\0\5" has 7 bytes because of the implicit null terminator.
PiperOrigin-RevId: 769253763
This is the new current version, so capture a test that
ensure it works so this are already set up for the next time
the generate format has to evolve.
PiperOrigin-RevId: 729193386
When a field is encoded normally in a MessageSet, only promote
it if it is a known extension, if it is an unknown extension, then leave
it as an unknown field.
PiperOrigin-RevId: 726062078
GPBUnknownFieldSet and the related apis have been replaced by
GPBUnknownFields. The new api allows the Objective-C Protobuf
implementation to be fully conformant around requirements for
parsing/re-serialization of unknown fields.
PiperOrigin-RevId: 684140581
As of C23, `va_start` no longer requires a second argument, and ignores it when provided. So, the parameter named `unused` is now...unused.
PiperOrigin-RevId: 683183750
Import both the public and private header into impls when the
private is needed.
Also update the tests to use more complete imports.
PiperOrigin-RevId: 671388271
Migrate some internals of the library off the older apis.
Also mark some of the old apis as deprecated, but the old generated code
suppressed warnings broadly to support protobuf deprecations.
PiperOrigin-RevId: 668003974
Since a group GPBUnknownField uses a GPBUnknownFields and that is mutable, it needs to be copied so two instances aren't linked.
PiperOrigin-RevId: 663323972
GPBUnknownFields will be going away in the next major release of the ObjC
Protobuf runtime. Code should be updated to make use of GPBUnknownFields
instead.
PiperOrigin-RevId: 659963056
`GPBTextFormatForMessage()` will contain any information for unknown fields.
And it clears the way for `GPBUnknownFieldSet` to eventually be deprecated
also.
PiperOrigin-RevId: 655184316
Make a new internal api for collecting up the unknown group fields
that will be used in a future change.
Add testing for the new api and for unknown field parsing of groups in
general.
PiperOrigin-RevId: 654875605
- Follow upb and only accept the first value for `type_id` and `message`
- Reflow some of the logic to hopefully make things a little easier to follow/clear.
- Validate some more assertion about things the extensions for a MessageSet.
PiperOrigin-RevId: 652545240
Ensure all apis are called directly in tests.
Correct `GPBUnknownField` `-copy` to not have to make a new instance
since it is immutable in the new form.
PiperOrigin-RevId: 650690942
Port of the interesting `GPBUnknownFieldsSet` tests to `GPBUnknownFields`
as they provide coverage of general handing of unknown fields during parsing.
Also tweak the `Set` tests to actually use a registry to confirm behaviors around
extensions where the test previously wasn't as complete.
PiperOrigin-RevId: 650660181
`GPBUnknownFields` additions:
- Provide `Optional` based apis for the `getFirst*` apis.
- Map the `NSFastEnumeration` over as a `Sequence` to support looping over the fields.
`GPBUnknownField` addition:
- Add an `enum` with associated values to provide a more type-safe way for inspection.
PiperOrigin-RevId: 649090744
`GPBUnknownFields` will be the eventually replacement for `GPBUnknownFieldSet`. This
introduces the type and the changes to `GPBUnknownField`.
The new api will preserve the wire ordering of unknown fields. This is now checked
in conformance tests.
While this adds the type changes and tests them, it does not yet wire the changes
in to the rest of the Runtime, so the conformance tests still done pass.
`GPBUnknownFieldSet` also hasn't been deprecated yet, that will come in later with
the wiring in to the runtime.
PiperOrigin-RevId: 648361455
This simply exposes preexisting logic. This read-only API is for convenience and doesn't reveal any information that was not already available. `[GPBCodedInputStream position]` is already a public API. The `limit` is known to the user because it's specified by them.
PiperOrigin-RevId: 635502694
This prevents shadowing of `java.lang` package commonly used in protobuf gencode. Existing extensions named `java` may or may not previously fail to compile depending on if the contents of their .proto result in gencode using `java.lang`. This is needed to fix `java_features.proto` lite gencode since enum gencode uses `java.lang`. Fields named `java` should already be escaped.
*Warning: This may break user code for existing protos with extensions named `java`. References to the extension should be renamed to use `java_` e.g. registry.add(GeneratedClassName.java_)*
PiperOrigin-RevId: 632508249
GPB_ENUM_FWD_DECLARE needs `int32_t`, so add the import so GPBBootstrap.h
stands on its own without needing users to import something else.
Add another compile test file to ensure this doesn't break.
PiperOrigin-RevId: 610403337