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