4040
4141#define THROW_AND_RETURN_IF_OOB (r ) \
4242 do { \
43- if (!(r)) \
43+ if ((r).IsNothing ()) return ; \
44+ if (!(r).FromJust ()) \
4445 return node::THROW_ERR_OUT_OF_RANGE (env, " Index out of range" ); \
4546 } while (0 ) \
4647
47- #define SLICE_START_END (start_arg, end_arg, end_max ) \
48+ #define SLICE_START_END (env, start_arg, end_arg, end_max ) \
4849 size_t start; \
4950 size_t end; \
50- THROW_AND_RETURN_IF_OOB (ParseArrayIndex(start_arg, 0 , &start)); \
51- THROW_AND_RETURN_IF_OOB (ParseArrayIndex(end_arg, end_max, &end)); \
51+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex(env, start_arg, 0 , &start)); \
52+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex(env, end_arg, end_max, &end)); \
5253 if (end < start) end = start; \
53- THROW_AND_RETURN_IF_OOB (end <= end_max); \
54+ THROW_AND_RETURN_IF_OOB (Just( end <= end_max)); \
5455 size_t length = end - start;
5556
5657namespace node {
@@ -75,9 +76,11 @@ using v8::EscapableHandleScope;
7576using v8::FunctionCallbackInfo;
7677using v8::Integer;
7778using v8::Isolate;
79+ using v8::Just;
7880using v8::Local;
7981using v8::Maybe;
8082using v8::MaybeLocal;
83+ using v8::Nothing;
8184using v8::Object;
8285using v8::String;
8386using v8::Uint32;
@@ -160,29 +163,32 @@ void CallbackInfo::WeakCallback(Isolate* isolate) {
160163}
161164
162165
163- // Parse index for external array data.
164- inline MUST_USE_RESULT bool ParseArrayIndex (Local<Value> arg,
165- size_t def,
166- size_t * ret) {
166+ // Parse index for external array data. An empty Maybe indicates
167+ // a pending exception. `false` indicates that the index is out-of-bounds.
168+ inline MUST_USE_RESULT Maybe<bool > ParseArrayIndex (Environment* env,
169+ Local<Value> arg,
170+ size_t def,
171+ size_t * ret) {
167172 if (arg->IsUndefined ()) {
168173 *ret = def;
169- return true ;
174+ return Just ( true ) ;
170175 }
171176
172- CHECK (arg->IsNumber ());
173- int64_t tmp_i = arg.As <Integer>()->Value ();
177+ int64_t tmp_i;
178+ if (!arg->IntegerValue (env->context ()).To (&tmp_i))
179+ return Nothing<bool >();
174180
175181 if (tmp_i < 0 )
176- return false ;
182+ return Just ( false ) ;
177183
178184 // Check that the result fits in a size_t.
179185 const uint64_t kSizeMax = static_cast <uint64_t >(static_cast <size_t >(-1 ));
180186 // coverity[pointless_expression]
181187 if (static_cast <uint64_t >(tmp_i) > kSizeMax )
182- return false ;
188+ return Just ( false ) ;
183189
184190 *ret = static_cast <size_t >(tmp_i);
185- return true ;
191+ return Just ( true ) ;
186192}
187193
188194} // anonymous namespace
@@ -467,7 +473,7 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
467473 if (ts_obj_length == 0 )
468474 return args.GetReturnValue ().SetEmptyString ();
469475
470- SLICE_START_END (args[0 ], args[1 ], ts_obj_length)
476+ SLICE_START_END (env, args[0 ], args[1 ], ts_obj_length)
471477
472478 Local<Value> error;
473479 MaybeLocal<Value> ret =
@@ -500,9 +506,10 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
500506 size_t source_start;
501507 size_t source_end;
502508
503- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[2 ], 0 , &target_start));
504- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[3 ], 0 , &source_start));
505- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[4 ], ts_obj_length, &source_end));
509+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[2 ], 0 , &target_start));
510+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[3 ], 0 , &source_start));
511+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[4 ], ts_obj_length,
512+ &source_end));
506513
507514 // Copy 0 bytes; we're done
508515 if (target_start >= target_length || source_start >= source_end)
@@ -633,13 +640,13 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
633640 size_t offset;
634641 size_t max_length;
635642
636- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[1 ], 0 , &offset));
643+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[1 ], 0 , &offset));
637644 if (offset > ts_obj_length) {
638645 return node::THROW_ERR_BUFFER_OUT_OF_BOUNDS (
639646 env, " \" offset\" is outside of buffer bounds" );
640647 }
641648
642- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[2 ], ts_obj_length - offset,
649+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[2 ], ts_obj_length - offset,
643650 &max_length));
644651
645652 max_length = MIN (ts_obj_length - offset, max_length);
@@ -694,10 +701,12 @@ void CompareOffset(const FunctionCallbackInfo<Value> &args) {
694701 size_t source_end;
695702 size_t target_end;
696703
697- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[2 ], 0 , &target_start));
698- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[3 ], 0 , &source_start));
699- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[4 ], target_length, &target_end));
700- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[5 ], ts_obj_length, &source_end));
704+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[2 ], 0 , &target_start));
705+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[3 ], 0 , &source_start));
706+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[4 ], target_length,
707+ &target_end));
708+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[5 ], ts_obj_length,
709+ &source_end));
701710
702711 if (source_start > ts_obj_length)
703712 return THROW_ERR_OUT_OF_RANGE (
0 commit comments