This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git
The following commit(s) were added to refs/heads/main by this push:
new b3b2761f0a 🔄 synced local 'docs/guide/' with remote 'docs/guide/'
b3b2761f0a is described below
commit b3b2761f0ae20c70a52cc6640dcf5b7946a612f8
Author: chaokunyang <[email protected]>
AuthorDate: Mon Aug 3 05:11:06 2026 +0000
🔄 synced local 'docs/guide/' with remote 'docs/guide/'
---
docs/guide/cpp/configuration.md | 13 +++++++++++++
docs/guide/csharp/configuration.md | 13 +++++++++++++
docs/guide/dart/configuration.md | 12 ++++++++++++
docs/guide/go/configuration.md | 13 +++++++++++++
docs/guide/java/configuration.md | 4 ++++
docs/guide/javascript/configuration.md | 9 +++++++++
docs/guide/kotlin/configuration.md | 8 ++++++++
docs/guide/python/configuration.md | 5 +++++
docs/guide/rust/configuration.md | 15 +++++++++++++++
docs/guide/scala/configuration.md | 8 ++++++++
docs/guide/swift/configuration.md | 6 ++++++
docs/guide/xlang/serialization.md | 23 +++++++++++++++++++++++
12 files changed, 129 insertions(+)
diff --git a/docs/guide/cpp/configuration.md b/docs/guide/cpp/configuration.md
index d72f82b330..77c6034794 100644
--- a/docs/guide/cpp/configuration.md
+++ b/docs/guide/cpp/configuration.md
@@ -120,6 +120,18 @@ leaf value.
**Default:** `128 MiB`
+### max_unbacked_container_items(int64_t)
+
+Limit collection elements and map entries whose repeated read bodies do not
+consume proportional input during one root deserialization. The default is
+`8192`; zero is a strict limit.
+
+```cpp
+auto fory = Fory::builder()
+ .max_unbacked_container_items(8192)
+ .build();
+```
+
### max_dyn_depth(uint32_t)
Set maximum allowed nesting depth for dynamically-typed objects.
@@ -230,6 +242,7 @@ auto fory = Fory::builder().build_thread_safe(); //
Returns ThreadSafeFory
| `compatible(bool)` | Enable schema evolution
| `true` |
| `track_ref(bool)` | Enable reference tracking
| `true` |
| `max_graph_memory_bytes(int64_t)` | Approximate graph-memory
gate per root read | `128 MiB` |
+| `max_unbacked_container_items(int64_t)` | Unbacked collection/map
work per root read | `8192` |
| `max_dyn_depth(uint32_t)` | Maximum nesting depth for
dynamic types | `5` |
| `max_type_fields(uint32_t)` | Max fields in one
received struct metadata body | `512` |
| `max_type_meta_bytes(uint32_t)` | Max encoded bytes in one
received metadata body | `4096` |
diff --git a/docs/guide/csharp/configuration.md
b/docs/guide/csharp/configuration.md
index b8891270d9..a7fbbea753 100644
--- a/docs/guide/csharp/configuration.md
+++ b/docs/guide/csharp/configuration.md
@@ -42,6 +42,7 @@ ThreadSafeFory threadSafe = Fory.Builder().BuildThreadSafe();
| `CheckStructVersion` | `false` | Struct schema hash checks
disabled |
| `MaxDepth` | `20` | Max dynamic nesting depth
|
| `MaxGraphMemoryBytes` | `134217728` | Approximate graph-memory
gate per root read |
+| `MaxUnbackedContainerItems` | `8192` | Unbacked collection/map
work per root read |
| `MaxTypeFields` | `512` | Max fields in one received
struct metadata body |
| `MaxTypeMetaBytes` | `4096` | Max encoded bytes in one
received metadata body |
| `MaxSchemaVersionsPerType` | `10` | Max remote metadata
versions for one logical type |
@@ -115,6 +116,18 @@ default. Explicit non-positive values are rejected when
the runtime is created.
are still gated by remaining input bytes: if the unread input does not contain
enough bytes, Fory
will not read or create that leaf value.
+### `MaxUnbackedContainerItems(long value)`
+
+Limits collection elements and map entries whose repeated read bodies do not
+consume proportional input during one root deserialization. The default is
+`8192`; zero is a strict limit.
+
+```csharp
+Fory fory = Fory.Builder()
+ .MaxUnbackedContainerItems(8192)
+ .Build();
+```
+
### `MaxTypeFields(int value)`
Sets the maximum fields accepted in one received remote struct metadata body.
diff --git a/docs/guide/dart/configuration.md b/docs/guide/dart/configuration.md
index 238700a6d5..82db00c804 100644
--- a/docs/guide/dart/configuration.md
+++ b/docs/guide/dart/configuration.md
@@ -39,6 +39,7 @@ final fory = Fory(
maxSchemaVersionsPerType: 10,
maxAverageSchemaVersionsPerType: 3,
maxGraphMemoryBytes: 64 * 1024 * 1024,
+ maxUnbackedContainerItems: 8192,
);
```
@@ -127,6 +128,16 @@ final fory = Fory(maxGraphMemoryBytes: 256 * 1024 * 1024);
Explicit non-positive values are rejected when the runtime is created.
+### `maxUnbackedContainerItems`
+
+Limits collection elements and map entries whose repeated read bodies do not
+consume proportional input during one root deserialization. The default is
+`8192`; zero is a strict limit.
+
+```dart
+final fory = Fory(maxUnbackedContainerItems: 8192);
+```
+
## Defaults
| Option | Default |
@@ -139,6 +150,7 @@ Explicit non-positive values are rejected when the runtime
is created.
| `maxSchemaVersionsPerType` | 10 |
| `maxAverageSchemaVersionsPerType` | 3 |
| `maxGraphMemoryBytes` | 134217728 |
+| `maxUnbackedContainerItems` | 8192 |
## Xlang Notes
diff --git a/docs/guide/go/configuration.md b/docs/guide/go/configuration.md
index 2ddad20800..55a9a2be10 100644
--- a/docs/guide/go/configuration.md
+++ b/docs/guide/go/configuration.md
@@ -40,6 +40,7 @@ Default settings:
| IsXlang | true | Xlang mode enabled
|
| Compatible | true | Compatible schema-evolution
metadata enabled |
| MaxGraphMemoryBytes | 134217728 | Approximate graph-memory gate
per root read |
+| MaxUnbackedContainerItems | 8192 | Unbacked collection/map work
per root read |
| MaxTypeFields | 512 | Max fields in one received
struct metadata body |
| MaxTypeMetaBytes | 4096 | Max encoded bytes in one
received metadata body |
| MaxSchemaVersionsPerType | 10 | Max remote metadata versions
for one logical type |
@@ -53,6 +54,7 @@ f := fory.New(
fory.WithTrackRef(true),
fory.WithMaxDepth(10),
fory.WithMaxGraphMemoryBytes(128 * 1024 * 1024),
+ fory.WithMaxUnbackedContainerItems(8192),
fory.WithMaxTypeFields(512),
fory.WithMaxTypeMetaBytes(4096),
fory.WithMaxSchemaVersionsPerType(10),
@@ -147,6 +149,17 @@ reservation complements byte-availability checks; it does
not replace them. Skip
still gated by remaining input bytes: if the unread input does not contain
enough bytes, Fory will
not read or create that leaf value.
+### WithMaxUnbackedContainerItems
+
+Limit collection elements and map entries whose repeated read bodies do not
+consume proportional input during one root deserialization:
+
+```go
+f := fory.New(fory.WithMaxUnbackedContainerItems(8192))
+```
+
+The default is `8192`; zero is a strict limit.
+
### WithMaxTypeFields
Set the maximum fields accepted in one received remote struct metadata body:
diff --git a/docs/guide/java/configuration.md b/docs/guide/java/configuration.md
index 7c4d47c9cb..ba59f6ba78 100644
--- a/docs/guide/java/configuration.md
+++ b/docs/guide/java/configuration.md
@@ -39,6 +39,7 @@ This page documents all configuration options available
through `ForyBuilder`.
| `requireClassRegistration` | Disabling may allow unknown classes to
be deserialized, potentially causing security risks.
[...]
| `maxDepth` | Set max depth for deserialization,
when depth exceeds, an exception will be thrown. This can be used to refuse
deserialization DDOS attack.
[...]
| `maxGraphMemoryBytes` | Approximate graph-memory gate for one
root deserialization. It mainly covers materialized collections, maps, arrays,
structs, and objects; leaf values are gated by remaining input bytes.
[...]
+| `maxUnbackedContainerItems` | Maximum collection elements and map
entries whose repeated read bodies are not backed by input progress during one
root deserialization. Zero is strict.
[...]
| `maxTypeFields` | Maximum fields accepted in one
received remote struct metadata body.
[...]
| `maxTypeMetaBytes` | Maximum encoded body bytes accepted
for one received TypeDef or TypeMeta body, excluding the 8-byte header and any
extended-size varint.
[...]
| `maxSchemaVersionsPerType` | Maximum accepted remote metadata
versions for one logical type.
[...]
@@ -92,6 +93,7 @@ Fory fory = Fory.builder()
.requireClassRegistration(true)
.withMaxDepth(50)
.withMaxGraphMemoryBytes(128L * 1024 * 1024)
+ .withMaxUnbackedContainerItems(8192)
.build();
```
@@ -106,6 +108,8 @@ Security-related options:
byte-availability checks: if the unread input does not contain enough bytes,
Fory will not read or
create that leaf value. The default is a fixed `128 MiB`; set a positive
byte limit when trusted
workloads need a larger or smaller gate.
+- `withMaxUnbackedContainerItems(...)` limits count-driven collection and map
work whose repeated
+ read bodies do not consume proportional input. The default is `8192`; zero
is a strict limit.
- `withMaxTypeFields(...)` and `withMaxTypeMetaBytes(...)` bound the field
count
and encoded body size of one received remote metadata body.
- `withMaxSchemaVersionsPerType(...)` and
diff --git a/docs/guide/javascript/configuration.md
b/docs/guide/javascript/configuration.md
index f3051a1b53..58830e76d4 100644
--- a/docs/guide/javascript/configuration.md
+++ b/docs/guide/javascript/configuration.md
@@ -44,6 +44,7 @@ const fory = new Fory({
compatible: true,
maxDepth: 100,
maxGraphMemoryBytes: 128 * 1024 * 1024,
+ maxUnbackedContainerItems: 8192,
maxTypeFields: 512,
maxTypeMetaBytes: 4096,
maxSchemaVersionsPerType: 10,
@@ -58,6 +59,7 @@ const fory = new Fory({
| `compatible` | `true` | Allow field
additions/removals without breaking existing messages |
| `maxDepth` | `50` | Maximum nesting depth. Must
be `>= 2`. Increase for deeply nested structures |
| `maxGraphMemoryBytes` | `128 MiB` | Approximate graph-memory
gate accepted during one root deserialization |
+| `maxUnbackedContainerItems` | `8192` | Unbacked collection elements
and map entries allowed during one root deserialization |
| `maxTypeFields` | `512` | Maximum fields accepted in
one received remote struct metadata body |
| `maxTypeMetaBytes` | `4096` | Maximum encoded body bytes
accepted for one received TypeMeta body |
| `maxSchemaVersionsPerType` | `10` | Maximum accepted remote
metadata versions for one logical type |
@@ -117,6 +119,13 @@ String, binary, and dedicated dense primitive array
payloads keep their normal
byte-size checks and do not consume this graph budget. Raise the limit only for
trusted workloads that legitimately contain very compact object graphs.
+## Unbacked Container Work Budget
+
+`maxUnbackedContainerItems` limits collection elements and map entries whose
+repeated read bodies do not consume proportional input during one root
+deserialization. The default is `8192`; zero is a strict limit. Raise it only
+for trusted payloads that intentionally use compact zero-byte codecs.
+
## Optional HPS String Path
`@apache-fory/hps` provides an optional Node.js string fast path:
diff --git a/docs/guide/kotlin/configuration.md
b/docs/guide/kotlin/configuration.md
index 069de266d2..aabeae9f0b 100644
--- a/docs/guide/kotlin/configuration.md
+++ b/docs/guide/kotlin/configuration.md
@@ -128,9 +128,14 @@ create that leaf value.
```kotlin
val fory = ForyKotlin.builder()
.withMaxGraphMemoryBytes(128L * 1024 * 1024)
+ .withMaxUnbackedContainerItems(8192)
.build()
```
+`withMaxUnbackedContainerItems(...)` limits collection elements and map
entries whose repeated
+read bodies do not consume proportional input during one root deserialization.
The default is
+`8192`; zero is a strict limit.
+
## Compatible Mode
Compatible mode is enabled by default through the Java builder in both xlang
and native mode. Keep
@@ -151,6 +156,7 @@ val fory = ForyKotlin.builder()
.requireClassRegistration(true)
.withMaxDepth(50)
.withMaxGraphMemoryBytes(128L * 1024 * 1024)
+ .withMaxUnbackedContainerItems(8192)
.withMaxTypeFields(512)
.withMaxTypeMetaBytes(4096)
.build()
@@ -163,6 +169,8 @@ Security-related configuration:
- Use `withMaxGraphMemoryBytes(...)` as an approximate gate for collection,
map, array, struct, and
object-heavy payloads. It is not an exact heap cap; leaf values are gated by
remaining input
bytes.
+- Keep `withMaxUnbackedContainerItems(...)` at `8192` unless trusted compact
codecs require a
+ larger root allowance. Zero rejects every unbacked item.
- Keep `withMaxTypeFields(...)`, `withMaxTypeMetaBytes(...)`, and the remote
schema-version limits
at their defaults unless the data is not malicious and a trusted peer sends
larger metadata or
many schema versions.
diff --git a/docs/guide/python/configuration.md
b/docs/guide/python/configuration.md
index 2714bf509a..4154cd4b7b 100644
--- a/docs/guide/python/configuration.md
+++ b/docs/guide/python/configuration.md
@@ -41,6 +41,7 @@ class Fory:
max_schema_versions_per_type: int = 10,
max_average_schema_versions_per_type: int = 3,
max_graph_memory_bytes: int = 128 * 1024 * 1024,
+ max_unbacked_container_items: int = 8192,
policy: DeserializationPolicy = None,
field_nullable: bool = False,
meta_compressor=None,
@@ -72,6 +73,7 @@ class ThreadSafeFory:
| `max_schema_versions_per_type` | `int` |
`10` | Maximum accepted remote metadata versions for one logical type.
|
| `max_average_schema_versions_per_type` | `int` |
`3` | Average accepted remote metadata versions across accepted remote
types. The effective global floor is `8192` schemas.
|
| `max_graph_memory_bytes` | `int` |
`134217728` | Approximate graph-memory gate for one root deserialization.
Explicit non-positive values are rejected.
|
+| `max_unbacked_container_items` | `int` |
`8192` | Maximum collection elements and map entries whose repeated reads
are not backed by input progress. Zero is strict.
|
| `policy` | `DeserializationPolicy \| None` |
`None` | Deserialization policy used for security checks. Strongly
recommended when `strict=False`.
|
| `field_nullable` | `bool` |
`False` | Treat dataclass fields as nullable by default.
|
| `meta_compressor` | `Any` |
`None` | Optional metadata compressor used for compatible-mode metadata
encoding.
|
@@ -233,6 +235,9 @@ Received remote metadata is also limited:
will not read or create that leaf value. The default is a fixed `128 MiB`
for all root input
forms. Set a positive byte value for trusted payloads that legitimately need
a larger or smaller
gate.
+- `max_unbacked_container_items` limits collection elements and map entries
whose repeated read
+ bodies do not consume proportional input during one root deserialization.
The default is `8192`;
+ zero is a strict limit.
These limits do not change `strict`, `policy`, dynamic loading, unknown-class
handling, or
schema-evolution semantics.
diff --git a/docs/guide/rust/configuration.md b/docs/guide/rust/configuration.md
index c851c56479..f357f40414 100644
--- a/docs/guide/rust/configuration.md
+++ b/docs/guide/rust/configuration.md
@@ -128,6 +128,18 @@ let fory = Fory::builder()
Zero is rejected when the runtime is created.
+### Unbacked Container Work Budget
+
+`max_unbacked_container_items(...)` limits collection elements and map entries
+whose repeated read bodies do not consume proportional input during one root
+deserialization. The default is `8192`; zero is a strict limit.
+
+```rust
+let fory = Fory::builder()
+ .max_unbacked_container_items(8192)
+ .build();
+```
+
### Explicit Xlang Examples
Set `.xlang(true)` explicitly for xlang serialization examples:
@@ -173,6 +185,7 @@ let fory = Fory::builder()
| `xlang(bool)` | Use xlang mode
| `true` |
| `max_dyn_depth(u32)` | Maximum nesting depth for
dynamic types | `5` |
| `max_graph_memory_bytes(usize)` | Approximate graph-memory
gate per root read | `128 MiB` |
+| `max_unbacked_container_items(usize)` | Unbacked collection/map work
per root read | `8192` |
| `max_type_fields(usize)` | Max fields in one received
struct metadata body | `512` |
| `max_type_meta_bytes(usize)` | Max encoded bytes in one
received metadata body | `4096` |
| `max_schema_versions_per_type(usize)` | Max remote metadata versions
for one logical type | `10` |
@@ -195,6 +208,8 @@ Security-related configuration:
- Use `max_dyn_depth(...)` to reject unexpectedly deep dynamic object graphs.
- Keep `max_graph_memory_bytes(...)` at the fixed `128 MiB` default for most
inputs, or set a
positive byte gate for trusted workloads with different legitimate
collection/map/struct sizes.
+- Keep `max_unbacked_container_items(...)` at `8192` unless trusted compact
codecs require a
+ larger root allowance. Zero rejects every unbacked item.
- Keep the remote schema metadata limits at their defaults unless the data is
not malicious and a
trusted peer sends larger metadata or many schema versions.
- Prefer concrete typed fields over `dyn Any` or broad trait-object fields for
untrusted input.
diff --git a/docs/guide/scala/configuration.md
b/docs/guide/scala/configuration.md
index 260c8d5a33..bcd60429d5 100644
--- a/docs/guide/scala/configuration.md
+++ b/docs/guide/scala/configuration.md
@@ -152,9 +152,14 @@ create that leaf value.
```scala
val fory = ForyScala.builder()
.withMaxGraphMemoryBytes(128L * 1024 * 1024)
+ .withMaxUnbackedContainerItems(8192)
.build()
```
+`withMaxUnbackedContainerItems(...)` limits collection elements and map
entries whose repeated
+read bodies do not consume proportional input during one root deserialization.
The default is
+`8192`; zero is a strict limit.
+
## Xlang Mode
For Scala xlang or schema IDL generated code, use the default xlang mode and
@@ -195,6 +200,7 @@ val fory = ForyScala.builder()
.requireClassRegistration(true)
.withMaxDepth(50)
.withMaxGraphMemoryBytes(128L * 1024 * 1024)
+ .withMaxUnbackedContainerItems(8192)
.withMaxTypeFields(512)
.withMaxTypeMetaBytes(4096)
.build()
@@ -207,6 +213,8 @@ Security-related configuration:
- Use `withMaxGraphMemoryBytes(...)` as an approximate gate for collection,
map, array, struct, and
object-heavy payloads. It is not an exact heap cap; leaf values are gated by
remaining input
bytes.
+- Keep `withMaxUnbackedContainerItems(...)` at `8192` unless trusted compact
codecs require a
+ larger root allowance. Zero rejects every unbacked item.
- Keep `withMaxTypeFields(...)`, `withMaxTypeMetaBytes(...)`, and the remote
schema-version limits
at their defaults unless the data is not malicious and a trusted peer sends
larger metadata or
many schema versions.
diff --git a/docs/guide/swift/configuration.md
b/docs/guide/swift/configuration.md
index 3dd20dd9ec..103c7d8dbb 100644
--- a/docs/guide/swift/configuration.md
+++ b/docs/guide/swift/configuration.md
@@ -32,6 +32,7 @@ public struct Config {
public let checkClassVersion: Bool
public let maxDepth: Int
public let maxGraphMemoryBytes: Int64
+ public let maxUnbackedContainerItems: Int
public let maxTypeFields: Int
public let maxTypeMetaBytes: Int
public let maxSchemaVersionsPerType: Int
@@ -106,6 +107,10 @@ byte-availability checks: if the unread input does not
contain enough bytes, For
create that leaf value. The default limit is a fixed `128 MiB` for all root
input forms. A positive
value overrides the default. Explicit non-positive values are rejected when
the runtime is created.
+`maxUnbackedContainerItems` limits collection elements and map entries whose
+repeated read bodies do not consume proportional input during one root
+deserialization. The default is `8192`; zero is a strict limit.
+
Compatible-mode remote metadata is also limited:
- `maxTypeFields` defaults to `512` and limits fields in one received struct
metadata body.
@@ -120,6 +125,7 @@ Compatible-mode remote metadata is also limited:
let fory = Fory(
maxDepth: 5,
maxGraphMemoryBytes: 128 * 1024 * 1024,
+ maxUnbackedContainerItems: 8192,
maxTypeFields: 512,
maxTypeMetaBytes: 4096,
maxSchemaVersionsPerType: 10,
diff --git a/docs/guide/xlang/serialization.md
b/docs/guide/xlang/serialization.md
index cdf136a353..7e5914f1e7 100644
--- a/docs/guide/xlang/serialization.md
+++ b/docs/guide/xlang/serialization.md
@@ -58,6 +58,29 @@ many schema versions.
| Swift | `maxTypeFields` | `maxTypeMetaBytes` |
`maxSchemaVersionsPerType` | `maxAverageSchemaVersionsPerType` |
| Dart | `maxTypeFields` | `maxTypeMetaBytes` |
`maxSchemaVersionsPerType` | `maxAverageSchemaVersionsPerType` |
+## Count-driven Container Work Limit
+
+Every runtime limits collection elements and map entries whose repeated read
+bodies do not consume proportional input. The default root allowance is `8192`.
+Zero is a strict limit, and negative values are rejected. Raise the limit only
+for trusted payloads that intentionally use compact zero-byte element codecs or
+empty Struct bodies. This is a reader resource limit and does not change the
+wire format or writer behavior.
+
+| Language | Option |
+| --------------------- | ------------------------------- |
+| Java | `withMaxUnbackedContainerItems` |
+| Scala | `withMaxUnbackedContainerItems` |
+| Kotlin | `withMaxUnbackedContainerItems` |
+| Python | `max_unbacked_container_items` |
+| JavaScript/TypeScript | `maxUnbackedContainerItems` |
+| C++ | `max_unbacked_container_items` |
+| Go | `WithMaxUnbackedContainerItems` |
+| Rust | `max_unbacked_container_items` |
+| C# | `MaxUnbackedContainerItems` |
+| Swift | `maxUnbackedContainerItems` |
+| Dart | `maxUnbackedContainerItems` |
+
## Serialize Built-in Types
Common types can be serialized automatically without registration: primitive
numeric types, string, binary, array, list, map, and more.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]