40
40
41
41
#define THROW_AND_RETURN_IF_OOB (r ) \
42
42
do { \
43
- if (!(r)) \
43
+ if ((r).IsNothing ()) return ; \
44
+ if (!(r).FromJust ()) \
44
45
return node::THROW_ERR_OUT_OF_RANGE (env, " Index out of range" ); \
45
46
} while (0 ) \
46
47
47
- #define SLICE_START_END (start_arg, end_arg, end_max ) \
48
+ #define SLICE_START_END (env, start_arg, end_arg, end_max ) \
48
49
size_t start; \
49
50
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)); \
52
53
if (end < start) end = start; \
53
- THROW_AND_RETURN_IF_OOB (end <= end_max); \
54
+ THROW_AND_RETURN_IF_OOB (Just( end <= end_max)); \
54
55
size_t length = end - start;
55
56
56
57
namespace node {
@@ -75,9 +76,11 @@ using v8::EscapableHandleScope;
75
76
using v8::FunctionCallbackInfo;
76
77
using v8::Integer;
77
78
using v8::Isolate;
79
+ using v8::Just;
78
80
using v8::Local;
79
81
using v8::Maybe;
80
82
using v8::MaybeLocal;
83
+ using v8::Nothing;
81
84
using v8::Object;
82
85
using v8::String;
83
86
using v8::Uint32;
@@ -160,29 +163,32 @@ void CallbackInfo::WeakCallback(Isolate* isolate) {
160
163
}
161
164
162
165
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) {
167
172
if (arg->IsUndefined ()) {
168
173
*ret = def;
169
- return true ;
174
+ return Just ( true ) ;
170
175
}
171
176
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 >();
174
180
175
181
if (tmp_i < 0 )
176
- return false ;
182
+ return Just ( false ) ;
177
183
178
184
// Check that the result fits in a size_t.
179
185
const uint64_t kSizeMax = static_cast <uint64_t >(static_cast <size_t >(-1 ));
180
186
// coverity[pointless_expression]
181
187
if (static_cast <uint64_t >(tmp_i) > kSizeMax )
182
- return false ;
188
+ return Just ( false ) ;
183
189
184
190
*ret = static_cast <size_t >(tmp_i);
185
- return true ;
191
+ return Just ( true ) ;
186
192
}
187
193
188
194
} // anonymous namespace
@@ -467,7 +473,7 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
467
473
if (ts_obj_length == 0 )
468
474
return args.GetReturnValue ().SetEmptyString ();
469
475
470
- SLICE_START_END (args[0 ], args[1 ], ts_obj_length)
476
+ SLICE_START_END (env, args[0 ], args[1 ], ts_obj_length)
471
477
472
478
Local<Value> error;
473
479
MaybeLocal<Value> ret =
@@ -500,9 +506,10 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
500
506
size_t source_start;
501
507
size_t source_end;
502
508
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));
506
513
507
514
// Copy 0 bytes; we're done
508
515
if (target_start >= target_length || source_start >= source_end)
@@ -633,13 +640,13 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
633
640
size_t offset;
634
641
size_t max_length;
635
642
636
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[1 ], 0 , &offset));
643
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[1 ], 0 , &offset));
637
644
if (offset > ts_obj_length) {
638
645
return node::THROW_ERR_BUFFER_OUT_OF_BOUNDS (
639
646
env, " \" offset\" is outside of buffer bounds" );
640
647
}
641
648
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,
643
650
&max_length));
644
651
645
652
max_length = MIN (ts_obj_length - offset, max_length);
@@ -694,10 +701,12 @@ void CompareOffset(const FunctionCallbackInfo<Value> &args) {
694
701
size_t source_end;
695
702
size_t target_end;
696
703
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));
701
710
702
711
if (source_start > ts_obj_length)
703
712
return THROW_ERR_OUT_OF_RANGE (
0 commit comments