This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/rhai_engine/rhaibook/safety/max-map-size.md
2025-04-03 09:18:05 +02:00

65 lines
2.5 KiB
Markdown

Maximum Size of Object Maps
===========================
{{#include ../links.md}}
Rhai by default does not limit how large (i.e. the number of properties) an [object map] can be.
This can be changed via `Engine::set_max_map_size`, with zero being unlimited (the default).
A script attempting to create an [object map] literal with more properties than the maximum will
terminate with a parse error.
Any script operation that produces an [object map] with more properties than the maximum also
terminates the script with an error.
This check can be disabled via the [`unchecked`] feature for higher performance (but higher risks as well).
```rust
let mut engine = Engine::new();
engine.set_max_map_size(500); // allow object maps with only up to 500 properties
engine.set_max_map_size(0); // allow unlimited object maps
```
~~~admonish danger "Maximum size"
Be conservative when setting a maximum limit and always consider the fact that a registered function
may grow an [object map]'s size without Rhai noticing until the very end.
For instance, the built-in `+` operator for [object maps] concatenates two [object maps] together to
form one larger [object map]; if both [object maps] are _slightly_ below the maximum size limit, the
resultant [object map] may be almost _twice_ the maximum size.
As a malicious script may create a deeply-nested [object map] which consumes huge amounts of memory
while each individual [object map] still stays under the maximum size limit, Rhai also _recursively_
adds up the sizes of all [strings], [arrays] and [object maps] contained within each [object map] to
make sure that the _aggregate_ sizes of none of these data structures exceed their respective
maximum size limits (if any).
```rust
// Small, innocent object map...
let small_map: #{ x: 42 }; // 1-deep... 1 item, 1 object map
// ... becomes huge when multiplied!
small_map.y = small_map; // 2-deep... 2 items, 2 object maps
small_map.y = small_map; // 3-deep... 4 items, 4 object maps
small_map.y = small_map; // 4-deep... 8 items, 8 object maps
small_map.y = small_map; // 5-deep... 16 items, 16 object maps
:
:
small_map.y = small_map; // <- Rhai raises an error somewhere here
small_map.y = small_map; // when the TOTAL number of items in
small_map.y = small_map; // the entire array tree exceeds limit
// Or this abomination...
let map = #{ x: 42 };
loop {
map.x = map; // <- only 1 item, but infinite number of object maps
}
```
~~~