Skip to content

Commit 5ea5912

Browse files
authored
Merge pull request #1346 from CosmWasm/make-limit_to_pages-32bit-friendly
Rewrite limit_to_pages to avoid storing 2^32 in u32
2 parents 955dd0c + e617039 commit 5ea5912

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

packages/vm/src/wasm_backend/store.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use super::limiting_tunables::LimitingTunables;
1818
/// is 65536 (2^16) bytes. In WebAssembly version 1, a linear memory can have at
1919
/// most 65536 pages, for a total of 2^32 bytes (4 gibibytes).
2020
/// https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md
21-
const MAX_WASM_MEMORY: usize = 4 * 1024 * 1024 * 1024;
21+
const MAX_WASM_PAGES: u32 = 65536;
2222

2323
fn cost(_operator: &Operator) -> u64 {
2424
// A flat fee for each operation
@@ -86,12 +86,17 @@ fn make_store_with_engine(engine: &dyn Engine, memory_limit: Option<Size>) -> St
8686
}
8787

8888
fn limit_to_pages(limit: Size) -> Pages {
89-
let capped = std::cmp::min(limit.0, MAX_WASM_MEMORY);
9089
// round down to ensure the limit is less than or equal to the config
91-
let pages: u32 = (capped / WASM_PAGE_SIZE)
92-
.try_into()
93-
.expect("Value must be <= 4 GiB/64KiB, i.e. fit in uint32. This is a bug.");
94-
Pages(pages)
90+
let limit_in_pages: usize = limit.0 / WASM_PAGE_SIZE;
91+
92+
let capped = match u32::try_from(limit_in_pages) {
93+
Ok(x) => std::cmp::min(x, MAX_WASM_PAGES),
94+
// The only case where TryFromIntError can happen is when
95+
// limit_in_pages exceeds the u32 range. In this case it is way
96+
// larger than MAX_WASM_PAGES and needs to be capped.
97+
Err(_too_large) => MAX_WASM_PAGES,
98+
};
99+
Pages(capped)
95100
}
96101

97102
#[cfg(test)]
@@ -113,10 +118,12 @@ mod tests {
113118
assert_eq!(limit_to_pages(Size::kibi(63)), Pages(0));
114119
assert_eq!(limit_to_pages(Size::kibi(64)), Pages(1));
115120
assert_eq!(limit_to_pages(Size::kibi(65)), Pages(1));
121+
assert_eq!(limit_to_pages(Size(u32::MAX as usize)), Pages(65535));
116122
// caps at 4 GiB
117123
assert_eq!(limit_to_pages(Size::gibi(3)), Pages(49152));
118124
assert_eq!(limit_to_pages(Size::gibi(4)), Pages(65536));
119125
assert_eq!(limit_to_pages(Size::gibi(5)), Pages(65536));
126+
assert_eq!(limit_to_pages(Size(usize::MAX)), Pages(65536));
120127
}
121128

122129
#[test]

0 commit comments

Comments
 (0)