Skip to content

Commit f8d6991

Browse files
committed
errors: use ERR_OUT_OF_RANGE for index errors
Remove ERR_INDEX_OUT_OF_RANGE in favor of ERR_OUT_OF_RANGE which is capable of providing more detail. (In one instance, use ERR_BUFFER_OUT_OF_BOUNDS which is more accurate in that one instance.) PR-URL: #22969 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Weijia Wang <starkwang@126.com>
1 parent 884dbe9 commit f8d6991

9 files changed

+104
-85
lines changed

doc/api/buffer.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,7 @@ console.log(buf1.compare(buf2, 5, 6, 5));
10851085
// Prints: 1
10861086
```
10871087

1088-
[`ERR_INDEX_OUT_OF_RANGE`] is thrown if `targetStart < 0`, `sourceStart < 0`,
1088+
[`ERR_OUT_OF_RANGE`] is thrown if `targetStart < 0`, `sourceStart < 0`,
10891089
`targetEnd > target.byteLength`, or `sourceEnd > source.byteLength`.
10901090

10911091
### buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
@@ -1197,6 +1197,9 @@ console.log(buf1.equals(buf3));
11971197
<!-- YAML
11981198
added: v0.5.0
11991199
changes:
1200+
- version: REPLACEME
1201+
pr-url: https://github.com/nodejs/node/pull/22969
1202+
description: Throws `ERR_OUT_OF_RANGE` instead of `ERR_INDEX_OUT_OF_RANGE`.
12001203
- version: v10.0.0
12011204
pr-url: https://github.com/nodejs/node/pull/18790
12021205
description: Negative `end` values throw an `ERR_INDEX_OUT_OF_RANGE` error.
@@ -1708,7 +1711,7 @@ console.log(buf.readIntLE(0, 6).toString(16));
17081711
console.log(buf.readIntBE(0, 6).toString(16));
17091712
// Prints: 1234567890ab
17101713
console.log(buf.readIntBE(1, 6).toString(16));
1711-
// Throws ERR_INDEX_OUT_OF_RANGE
1714+
// Throws ERR_OUT_OF_RANGE
17121715
console.log(buf.readIntBE(1, 0).toString(16));
17131716
// Throws ERR_OUT_OF_RANGE
17141717
```
@@ -2640,9 +2643,9 @@ This value may depend on the JS engine that is being used.
26402643
[`Buffer.from(string)`]: #buffer_class_method_buffer_from_string_encoding
26412644
[`Buffer.poolSize`]: #buffer_class_property_buffer_poolsize
26422645
[`DataView`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
2643-
[`ERR_INDEX_OUT_OF_RANGE`]: errors.html#ERR_INDEX_OUT_OF_RANGE
26442646
[`ERR_INVALID_BUFFER_SIZE`]: errors.html#ERR_INVALID_BUFFER_SIZE
26452647
[`ERR_INVALID_OPT_VALUE`]: errors.html#ERR_INVALID_OPT_VALUE
2648+
[`ERR_OUT_OF_RANGE`]: errors.html#ERR_OUT_OF_RANGE
26462649
[`JSON.stringify()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
26472650
[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
26482651
[`String#indexOf()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf

doc/api/errors.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -1102,11 +1102,6 @@ is set for the `Http2Stream`.
11021102
`http2.connect()` was passed a URL that uses any protocol other than `http:` or
11031103
`https:`.
11041104

1105-
<a id="ERR_INDEX_OUT_OF_RANGE"></a>
1106-
### ERR_INDEX_OUT_OF_RANGE
1107-
1108-
A given index was out of the accepted range (e.g. negative offsets).
1109-
11101105
<a id="ERR_INSPECTOR_ALREADY_CONNECTED"></a>
11111106
### ERR_INSPECTOR_ALREADY_CONNECTED
11121107

@@ -1930,6 +1925,14 @@ removed: v10.0.0
19301925
Used when an invalid character is found in an HTTP response status message
19311926
(reason phrase).
19321927

1928+
<a id="ERR_INDEX_OUT_OF_RANGE"></a>
1929+
### ERR_INDEX_OUT_OF_RANGE
1930+
<!-- YAML
1931+
added: v10.0.0
1932+
removed: REPLACEME
1933+
-->
1934+
A given index was out of the accepted range (e.g. negative offsets).
1935+
19331936
<a id="ERR_NAPI_CONS_PROTOTYPE_OBJECT"></a>
19341937
### ERR_NAPI_CONS_PROTOTYPE_OBJECT
19351938
<!-- YAML

lib/buffer.js

+56-55
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const {
6161
} = process.binding('config');
6262
const {
6363
ERR_BUFFER_OUT_OF_BOUNDS,
64-
ERR_INDEX_OUT_OF_RANGE,
64+
ERR_OUT_OF_RANGE,
6565
ERR_INVALID_ARG_TYPE,
6666
ERR_INVALID_ARG_VALUE,
6767
ERR_INVALID_BUFFER_SIZE,
@@ -692,50 +692,51 @@ Buffer.prototype[customInspectSymbol] = function inspect() {
692692
Buffer.prototype.inspect = Buffer.prototype[customInspectSymbol];
693693

694694
Buffer.prototype.compare = function compare(target,
695-
start,
696-
end,
697-
thisStart,
698-
thisEnd) {
695+
targetStart,
696+
targetEnd,
697+
sourceStart,
698+
sourceEnd) {
699699
if (!isUint8Array(target)) {
700700
throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target);
701701
}
702702
if (arguments.length === 1)
703703
return _compare(this, target);
704704

705-
if (start === undefined)
706-
start = 0;
707-
else if (start < 0)
708-
throw new ERR_INDEX_OUT_OF_RANGE();
705+
if (targetStart === undefined)
706+
targetStart = 0;
707+
else if (targetStart < 0)
708+
throw new ERR_OUT_OF_RANGE('targetStart', '>= 0', targetStart);
709709
else
710-
start >>>= 0;
710+
targetStart >>>= 0;
711711

712-
if (end === undefined)
713-
end = target.length;
714-
else if (end > target.length)
715-
throw new ERR_INDEX_OUT_OF_RANGE();
712+
if (targetEnd === undefined)
713+
targetEnd = target.length;
714+
else if (targetEnd > target.length)
715+
throw new ERR_OUT_OF_RANGE('targetEnd', `<= ${target.length}`, targetEnd);
716716
else
717-
end >>>= 0;
717+
targetEnd >>>= 0;
718718

719-
if (thisStart === undefined)
720-
thisStart = 0;
721-
else if (thisStart < 0)
722-
throw new ERR_INDEX_OUT_OF_RANGE();
719+
if (sourceStart === undefined)
720+
sourceStart = 0;
721+
else if (sourceStart < 0)
722+
throw new ERR_OUT_OF_RANGE('sourceStart', '>= 0', sourceStart);
723723
else
724-
thisStart >>>= 0;
724+
sourceStart >>>= 0;
725725

726-
if (thisEnd === undefined)
727-
thisEnd = this.length;
728-
else if (thisEnd > this.length)
729-
throw new ERR_INDEX_OUT_OF_RANGE();
726+
if (sourceEnd === undefined)
727+
sourceEnd = this.length;
728+
else if (sourceEnd > this.length)
729+
throw new ERR_OUT_OF_RANGE('sourceEnd', `<= ${this.length}`, sourceEnd);
730730
else
731-
thisEnd >>>= 0;
731+
sourceEnd >>>= 0;
732732

733-
if (thisStart >= thisEnd)
734-
return (start >= end ? 0 : -1);
735-
else if (start >= end)
733+
if (sourceStart >= sourceEnd)
734+
return (targetStart >= targetEnd ? 0 : -1);
735+
else if (targetStart >= targetEnd)
736736
return 1;
737737

738-
return compareOffset(this, target, start, thisStart, end, thisEnd);
738+
return compareOffset(this, target, targetStart, sourceStart, targetEnd,
739+
sourceEnd);
739740
};
740741

741742
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
@@ -827,15 +828,15 @@ Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
827828
// buffer.fill(number[, offset[, end]])
828829
// buffer.fill(buffer[, offset[, end]])
829830
// buffer.fill(string[, offset[, end]][, encoding])
830-
Buffer.prototype.fill = function fill(val, start, end, encoding) {
831-
return _fill(this, val, start, end, encoding);
831+
Buffer.prototype.fill = function fill(value, offset, end, encoding) {
832+
return _fill(this, value, offset, end, encoding);
832833
};
833834

834-
function _fill(buf, val, start, end, encoding) {
835-
if (typeof val === 'string') {
836-
if (start === undefined || typeof start === 'string') {
837-
encoding = start;
838-
start = 0;
835+
function _fill(buf, value, offset, end, encoding) {
836+
if (typeof value === 'string') {
837+
if (offset === undefined || typeof offset === 'string') {
838+
encoding = offset;
839+
offset = 0;
839840
end = buf.length;
840841
} else if (typeof end === 'string') {
841842
encoding = end;
@@ -848,48 +849,48 @@ function _fill(buf, val, start, end, encoding) {
848849
throw new ERR_UNKNOWN_ENCODING(encoding);
849850
}
850851

851-
if (val.length === 0) {
852-
// If val === '' default to zero.
853-
val = 0;
854-
} else if (val.length === 1) {
855-
// Fast path: If `val` fits into a single byte, use that numeric value.
852+
if (value.length === 0) {
853+
// If value === '' default to zero.
854+
value = 0;
855+
} else if (value.length === 1) {
856+
// Fast path: If `value` fits into a single byte, use that numeric value.
856857
if (normalizedEncoding === 'utf8') {
857-
const code = val.charCodeAt(0);
858+
const code = value.charCodeAt(0);
858859
if (code < 128) {
859-
val = code;
860+
value = code;
860861
}
861862
} else if (normalizedEncoding === 'latin1') {
862-
val = val.charCodeAt(0);
863+
value = value.charCodeAt(0);
863864
}
864865
}
865866
} else {
866867
encoding = undefined;
867868
}
868869

869-
if (start === undefined) {
870-
start = 0;
870+
if (offset === undefined) {
871+
offset = 0;
871872
end = buf.length;
872873
} else {
873874
// Invalid ranges are not set to a default, so can range check early.
875+
if (offset < 0)
876+
throw new ERR_OUT_OF_RANGE('offset', '>= 0', offset);
874877
if (end === undefined) {
875-
if (start < 0)
876-
throw new ERR_INDEX_OUT_OF_RANGE();
877878
end = buf.length;
878879
} else {
879-
if (start < 0 || end > buf.length || end < 0)
880-
throw new ERR_INDEX_OUT_OF_RANGE();
880+
if (end > buf.length || end < 0)
881+
throw new ERR_OUT_OF_RANGE('end', `>= 0 and <= ${buf.length}`, end);
881882
end = end >>> 0;
882883
}
883-
start = start >>> 0;
884-
if (start >= end)
884+
offset = offset >>> 0;
885+
if (offset >= end)
885886
return buf;
886887
}
887888

888-
const res = bindingFill(buf, val, start, end, encoding);
889+
const res = bindingFill(buf, value, offset, end, encoding);
889890
if (res < 0) {
890891
if (res === -1)
891-
throw new ERR_INVALID_ARG_VALUE('value', val);
892-
throw new ERR_INDEX_OUT_OF_RANGE();
892+
throw new ERR_INVALID_ARG_VALUE('value', value);
893+
throw new ERR_BUFFER_OUT_OF_BOUNDS();
893894
}
894895

895896
return buf;

lib/internal/errors.js

-1
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,6 @@ E('ERR_HTTP_INVALID_HEADER_VALUE',
625625
E('ERR_HTTP_INVALID_STATUS_CODE', 'Invalid status code: %s', RangeError);
626626
E('ERR_HTTP_TRAILER_INVALID',
627627
'Trailers are invalid with this transfer encoding', Error);
628-
E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range', RangeError);
629628
E('ERR_INSPECTOR_ALREADY_CONNECTED', '%s is already connected', Error);
630629
E('ERR_INSPECTOR_CLOSED', 'Session was closed', Error);
631630
E('ERR_INSPECTOR_NOT_AVAILABLE', 'Inspector is not available', Error);

src/node_buffer.cc

+11-6
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@
3636
#define MIN(a, b) ((a) < (b) ? (a) : (b))
3737

3838
#define THROW_AND_RETURN_UNLESS_BUFFER(env, obj) \
39-
THROW_AND_RETURN_IF_NOT_BUFFER(env, obj, "argument")
39+
THROW_AND_RETURN_IF_NOT_BUFFER(env, obj, "argument") \
4040

4141
#define THROW_AND_RETURN_IF_OOB(r) \
4242
do { \
43-
if (!(r)) return node::THROW_ERR_INDEX_OUT_OF_RANGE(env); \
44-
} while (0)
43+
if (!(r)) \
44+
return node::THROW_ERR_OUT_OF_RANGE_WITH_TEXT(env, \
45+
"Index out of range"); \
46+
} while (0) \
4547

4648
#define SLICE_START_END(start_arg, end_arg, end_max) \
4749
size_t start; \
@@ -494,7 +496,8 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
494496
return args.GetReturnValue().Set(0);
495497

496498
if (source_start > ts_obj_length)
497-
return node::THROW_ERR_INDEX_OUT_OF_RANGE(env);
499+
return node::THROW_ERR_OUT_OF_RANGE_WITH_TEXT(
500+
env, "The value of \"sourceStart\" is out of range.");
498501

499502
if (source_end - source_start > target_length - target_start)
500503
source_end = source_start + target_length - target_start;
@@ -684,9 +687,11 @@ void CompareOffset(const FunctionCallbackInfo<Value> &args) {
684687
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(args[5], ts_obj_length, &source_end));
685688

686689
if (source_start > ts_obj_length)
687-
return node::THROW_ERR_INDEX_OUT_OF_RANGE(env);
690+
return node::THROW_ERR_OUT_OF_RANGE_WITH_TEXT(
691+
env, "The value of \"sourceStart\" is out of range.");
688692
if (target_start > target_length)
689-
return node::THROW_ERR_INDEX_OUT_OF_RANGE(env);
693+
return node::THROW_ERR_OUT_OF_RANGE_WITH_TEXT(
694+
env, "The value of \"targetStart\" is out of range.");
690695

691696
CHECK_LE(source_start, source_end);
692697
CHECK_LE(target_start, target_end);

src/node_errors.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ namespace node {
2626
V(ERR_CANNOT_TRANSFER_OBJECT, TypeError) \
2727
V(ERR_CLOSED_MESSAGE_PORT, Error) \
2828
V(ERR_CONSTRUCT_CALL_REQUIRED, Error) \
29-
V(ERR_INDEX_OUT_OF_RANGE, RangeError) \
3029
V(ERR_INVALID_ARG_VALUE, TypeError) \
3130
V(ERR_INVALID_ARG_TYPE, TypeError) \
3231
V(ERR_INVALID_TRANSFER_OBJECT, TypeError) \
@@ -35,6 +34,7 @@ namespace node {
3534
V(ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST, TypeError) \
3635
V(ERR_MISSING_MODULE, Error) \
3736
V(ERR_MISSING_PLATFORM_FOR_WORKER, Error) \
37+
V(ERR_OUT_OF_RANGE, RangeError) \
3838
V(ERR_SCRIPT_EXECUTION_INTERRUPTED, Error) \
3939
V(ERR_SCRIPT_EXECUTION_TIMEOUT, Error) \
4040
V(ERR_STRING_TOO_LONG, Error) \
@@ -64,7 +64,6 @@ namespace node {
6464
V(ERR_CANNOT_TRANSFER_OBJECT, "Cannot transfer object of unsupported type")\
6565
V(ERR_CLOSED_MESSAGE_PORT, "Cannot send data on closed MessagePort") \
6666
V(ERR_CONSTRUCT_CALL_REQUIRED, "Cannot call constructor without `new`") \
67-
V(ERR_INDEX_OUT_OF_RANGE, "Index out of range") \
6867
V(ERR_INVALID_TRANSFER_OBJECT, "Found invalid object in transferList") \
6968
V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory") \
7069
V(ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST, \
@@ -96,6 +95,13 @@ inline void THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(Environment* env,
9695
THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, message.str().c_str());
9796
}
9897

98+
inline void THROW_ERR_OUT_OF_RANGE_WITH_TEXT(Environment* env,
99+
const char* messageText) {
100+
std::ostringstream message;
101+
message << messageText;
102+
THROW_ERR_OUT_OF_RANGE(env, message.str().c_str());
103+
}
104+
99105
inline v8::Local<v8::Value> ERR_BUFFER_TOO_LARGE(v8::Isolate* isolate) {
100106
char message[128];
101107
snprintf(message, sizeof(message),

test/parallel/test-buffer-alloc.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1011,9 +1011,8 @@ common.expectsError(() => {
10111011
const b = Buffer.alloc(1);
10121012
a.copy(b, 0, 0x100000000, 0x100000001);
10131013
}, {
1014-
code: 'ERR_INDEX_OUT_OF_RANGE',
1015-
type: RangeError,
1016-
message: 'Index out of range'
1014+
code: 'ERR_OUT_OF_RANGE',
1015+
type: RangeError
10171016
});
10181017

10191018
// Unpooled buffer (replaces SlowBuffer)

test/parallel/test-buffer-compare-offset.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ assert.strictEqual(1, a.compare(b, Infinity, -Infinity));
5757
// zero length target because default for targetEnd <= targetSource
5858
assert.strictEqual(1, a.compare(b, '0xff'));
5959

60-
const oor = common.expectsError({ code: 'ERR_INDEX_OUT_OF_RANGE' }, 7);
60+
const oor = common.expectsError({ code: 'ERR_OUT_OF_RANGE' }, 7);
6161

6262
assert.throws(() => a.compare(b, 0, 100, 0), oor);
6363
assert.throws(() => a.compare(b, 0, 1, 0, 100), oor);

0 commit comments

Comments
 (0)