@@ -1146,17 +1146,23 @@ bool MapWorkerPriorityName(const std::string &name, int &priority) {
11461146 return true ;
11471147}
11481148
1149- // Nice values outside the kernel's range are clamped rather than rejected:
1150- // a caller asking for "as low as possible" gets it.
1151- int ClampWorkerPriority (Local<Context> context, Local<Value> value) {
1152- int priority = value->Int32Value (context).FromMaybe (kDefaultWorkerPriority );
1149+ // Nice values outside the kernel's range are clamped rather than rejected: a
1150+ // caller asking for "as low as possible" gets it. Clamping happens on the
1151+ // double, before any integer conversion - ToInt32 wraps modulo 2^32, which
1152+ // would turn a value past the range into an in-range one. NaN sits on no point
1153+ // of the scale and is left to the caller to accept or reject.
1154+ std::optional<int > ClampWorkerPriority (Local<Value> value) {
1155+ double priority = value.As <Number>()->Value ();
1156+ if (std::isnan (priority)) {
1157+ return std::nullopt ;
1158+ }
11531159 if (priority < -20 ) {
11541160 return -20 ;
11551161 }
11561162 if (priority > 19 ) {
11571163 return 19 ;
11581164 }
1159- return priority;
1165+ return static_cast < int >( priority) ;
11601166}
11611167
11621168// Carries a real TypeError instance so `catch (e) { e instanceof TypeError }`
@@ -1205,15 +1211,22 @@ bool GetWorkerThreadPriority(Isolate *isolate, Local<Context> context,
12051211 return false ;
12061212 }
12071213 if (!priorityVal->IsUndefined ()) {
1214+ std::optional<int > resolvedPriority;
12081215 if (priorityVal->IsNumber ()) {
1209- priority = ClampWorkerPriority (context, priorityVal);
1210- } else if (!priorityVal->IsString () ||
1211- !MapWorkerPriorityName (
1212- ArgConverter::ConvertToString (priorityVal.As <String>()), priority)) {
1216+ resolvedPriority = ClampWorkerPriority (priorityVal);
1217+ } else if (priorityVal->IsString ()) {
1218+ int named;
1219+ if (MapWorkerPriorityName (ArgConverter::ConvertToString (priorityVal.As <String>()),
1220+ named)) {
1221+ resolvedPriority = named;
1222+ }
1223+ }
1224+ if (!resolvedPriority) {
12131225 ThrowWorkerOptionTypeError (
12141226 isolate, std::string (" Worker option \" android.priority\" must be one of " ) +
12151227 kWorkerPriorityNames + " ." );
12161228 }
1229+ priority = *resolvedPriority;
12171230 resolved = true ;
12181231 }
12191232 }
@@ -1237,7 +1250,9 @@ bool GetWorkerThreadPriority(Isolate *isolate, Local<Context> context,
12371250 }
12381251
12391252 if (legacyVal->IsNumber ()) {
1240- priority = ClampWorkerPriority (context, legacyVal);
1253+ // The deprecated option takes NaN as nice 0 (THREAD_PRIORITY_DEFAULT)
1254+ // rather than rejecting it.
1255+ priority = ClampWorkerPriority (legacyVal).value_or (0 );
12411256 return true ;
12421257 }
12431258 if (legacyVal->IsString () &&
0 commit comments