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
@@ -465,7 +471,7 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
465
471
if (ts_obj_length == 0 )
466
472
return args.GetReturnValue ().SetEmptyString ();
467
473
468
- SLICE_START_END (args[0 ], args[1 ], ts_obj_length)
474
+ SLICE_START_END (env, args[0 ], args[1 ], ts_obj_length)
469
475
470
476
Local<Value> error;
471
477
MaybeLocal<Value> ret =
@@ -498,9 +504,10 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
498
504
size_t source_start;
499
505
size_t source_end;
500
506
501
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[2 ], 0 , &target_start));
502
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[3 ], 0 , &source_start));
503
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[4 ], ts_obj_length, &source_end));
507
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[2 ], 0 , &target_start));
508
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[3 ], 0 , &source_start));
509
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[4 ], ts_obj_length,
510
+ &source_end));
504
511
505
512
// Copy 0 bytes; we're done
506
513
if (target_start >= target_length || source_start >= source_end)
@@ -631,13 +638,13 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
631
638
size_t offset;
632
639
size_t max_length;
633
640
634
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[1 ], 0 , &offset));
641
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[1 ], 0 , &offset));
635
642
if (offset > ts_obj_length) {
636
643
return node::THROW_ERR_BUFFER_OUT_OF_BOUNDS (
637
644
env, " \" offset\" is outside of buffer bounds" );
638
645
}
639
646
640
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[2 ], ts_obj_length - offset,
647
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[2 ], ts_obj_length - offset,
641
648
&max_length));
642
649
643
650
max_length = MIN (ts_obj_length - offset, max_length);
@@ -692,10 +699,12 @@ void CompareOffset(const FunctionCallbackInfo<Value> &args) {
692
699
size_t source_end;
693
700
size_t target_end;
694
701
695
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[2 ], 0 , &target_start));
696
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[3 ], 0 , &source_start));
697
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[4 ], target_length, &target_end));
698
- THROW_AND_RETURN_IF_OOB (ParseArrayIndex (args[5 ], ts_obj_length, &source_end));
702
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[2 ], 0 , &target_start));
703
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[3 ], 0 , &source_start));
704
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[4 ], target_length,
705
+ &target_end));
706
+ THROW_AND_RETURN_IF_OOB (ParseArrayIndex (env, args[5 ], ts_obj_length,
707
+ &source_end));
699
708
700
709
if (source_start > ts_obj_length)
701
710
return THROW_ERR_OUT_OF_RANGE (
0 commit comments