Skip to content

Commit 3b76a69

Browse files
committed
fix: cap resourceLimits to the platform's size_t range
1 parent 9a30fe7 commit 3b76a69

2 files changed

Lines changed: 15 additions & 6 deletions

File tree

‎test-app/app/src/main/assets/app/tests/testWorkerResourceLimits.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,12 @@ describe("Worker resourceLimits", function () {
100100
}).toThrowError(RangeError, /"resourceLimits\.maxYoungGenerationSizeMb"/);
101101
});
102102

103+
// The cap is derived from size_t, so it differs per ABI: 4095 MB where
104+
// size_t is 32 bits (armeabi-v7a, x86), (2^44 - 1) MB where it is 64. The
105+
// value has to sit above both for the spec to mean anything on every ABI.
103106
it("throws a RangeError for a maxOldGenerationSizeMb too large to hold in bytes", function () {
104107
expect(function () {
105-
new Worker(echoEntry, { resourceLimits: { maxOldGenerationSizeMb: Number.MAX_VALUE } });
108+
new Worker(echoEntry, { resourceLimits: { maxOldGenerationSizeMb: Math.pow(2, 53) } });
106109
}).toThrowError(RangeError, /"resourceLimits\.maxOldGenerationSizeMb"/);
107110
});
108111

‎test-app/runtime/src/main/cpp/CallbackHandlers.cpp‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "v8-profiler.h"
1313
#include <cmath>
1414
#include <iostream>
15+
#include <limits>
1516
#include <optional>
1617
#include <sstream>
1718
#include <fstream>
@@ -1280,9 +1281,12 @@ bool GetWorkerThreadPriority(Isolate *isolate, Local<Context> context,
12801281
}
12811282

12821283
constexpr double kBytesPerMegabyte = 1024 * 1024;
1283-
// Bounds the double-to-size_t conversion below; v8 clamps heap sizes far under
1284-
// this on every device, so nothing real is excluded.
1285-
constexpr double kMaxLimitMegabytes = 1024.0 * 1024.0;
1284+
// Bounds the double-to-size_t conversion below: converting a byte count that
1285+
// does not fit size_t is undefined, and size_t is 32 bits on armeabi-v7a and
1286+
// x86. The division floors, so the product always fits. v8 clamps heap sizes
1287+
// far under this on every device, so nothing real is excluded.
1288+
constexpr size_t kMaxLimitMegabytes =
1289+
std::numeric_limits<size_t>::max() / static_cast<size_t>(kBytesPerMegabyte);
12861290

12871291
// v8 needs the reservation to be a whole number of table segments and no larger
12881292
// than its compile-time maximum; whole megabytes satisfy the first on every
@@ -1317,11 +1321,13 @@ bool ReadMegabyteLimit(Isolate *isolate, Local<Context> context, Local<Object> r
13171321
}
13181322

13191323
double parsed = value.As<Number>()->Value();
1320-
if (!std::isfinite(parsed) || parsed * kBytesPerMegabyte < 1 || parsed > kMaxLimitMegabytes) {
1324+
if (!std::isfinite(parsed) || parsed * kBytesPerMegabyte < 1 ||
1325+
parsed > static_cast<double>(kMaxLimitMegabytes)) {
13211326
ThrowWorkerOptionRangeError(isolate,
13221327
"Worker option \"" + name +
13231328
"\" must be a finite number of megabytes worth at "
1324-
"least one byte and at most 1048576.");
1329+
"least one byte and at most " +
1330+
std::to_string(kMaxLimitMegabytes) + ".");
13251331
}
13261332

13271333
megabytes = parsed;

0 commit comments

Comments
 (0)