mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
buffer: use stricter range checks
This validates the input to make sure the arguments do not overflow. Before, if the input would overflow, it would cause the write to be performt in the wrong spot / result in unexpected behavior. Instead, just use a strict number validation. PR-URL: https://github.com/nodejs/node/pull/27045 Fixes: https://github.com/nodejs/node/issues/27043 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
7 files changed
+98
-102
No files matched your search
+30
-43
@@ -65,17 +65,18 @@ const {
|
||||
const {
|
||||
codes: {
|
||||
ERR_BUFFER_OUT_OF_BOUNDS,
|
||||
ERR_OUT_OF_RANGE,
|
||||
ERR_INVALID_ARG_TYPE,
|
||||
ERR_INVALID_ARG_VALUE,
|
||||
ERR_INVALID_BUFFER_SIZE,
|
||||
ERR_INVALID_OPT_VALUE,
|
||||
ERR_NO_LONGER_SUPPORTED,
|
||||
ERR_UNKNOWN_ENCODING
|
||||
},
|
||||
hideStackFrames
|
||||
} = require('internal/errors');
|
||||
const { validateString } = require('internal/validators');
|
||||
const {
|
||||
validateInt32,
|
||||
validateString
|
||||
} = require('internal/validators');
|
||||
|
||||
const {
|
||||
FastBuffer,
|
||||
@@ -445,7 +446,7 @@ Buffer.concat = function concat(list, length) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
length = length >>> 0;
|
||||
validateInt32(length, 'length', 0);
|
||||
}
|
||||
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
@@ -700,35 +701,27 @@ Buffer.prototype.compare = function compare(target,
|
||||
|
||||
if (targetStart === undefined)
|
||||
targetStart = 0;
|
||||
else if (targetStart < 0)
|
||||
throw new ERR_OUT_OF_RANGE('targetStart', '>= 0', targetStart);
|
||||
else
|
||||
targetStart >>>= 0;
|
||||
validateInt32(targetStart, 'targetStart', 0);
|
||||
|
||||
if (targetEnd === undefined)
|
||||
targetEnd = target.length;
|
||||
else if (targetEnd > target.length)
|
||||
throw new ERR_OUT_OF_RANGE('targetEnd', `<= ${target.length}`, targetEnd);
|
||||
else
|
||||
targetEnd >>>= 0;
|
||||
validateInt32(targetEnd, 'targetEnd', 0, target.length);
|
||||
|
||||
if (sourceStart === undefined)
|
||||
sourceStart = 0;
|
||||
else if (sourceStart < 0)
|
||||
throw new ERR_OUT_OF_RANGE('sourceStart', '>= 0', sourceStart);
|
||||
else
|
||||
sourceStart >>>= 0;
|
||||
validateInt32(sourceStart, 'sourceStart', 0);
|
||||
|
||||
if (sourceEnd === undefined)
|
||||
sourceEnd = this.length;
|
||||
else if (sourceEnd > this.length)
|
||||
throw new ERR_OUT_OF_RANGE('sourceEnd', `<= ${this.length}`, sourceEnd);
|
||||
else
|
||||
sourceEnd >>>= 0;
|
||||
validateInt32(sourceEnd, 'sourceEnd', 0, this.length);
|
||||
|
||||
if (sourceStart >= sourceEnd)
|
||||
return (targetStart >= targetEnd ? 0 : -1);
|
||||
else if (targetStart >= targetEnd)
|
||||
if (targetStart >= targetEnd)
|
||||
return 1;
|
||||
|
||||
return compareOffset(this, target, targetStart, sourceStart, targetEnd,
|
||||
@@ -867,17 +860,13 @@ function _fill(buf, value, offset, end, encoding) {
|
||||
offset = 0;
|
||||
end = buf.length;
|
||||
} else {
|
||||
validateInt32(offset, 'offset', 0);
|
||||
// Invalid ranges are not set to a default, so can range check early.
|
||||
if (offset < 0)
|
||||
throw new ERR_OUT_OF_RANGE('offset', '>= 0', offset);
|
||||
if (end === undefined) {
|
||||
end = buf.length;
|
||||
} else {
|
||||
if (end > buf.length || end < 0)
|
||||
throw new ERR_OUT_OF_RANGE('end', `>= 0 and <= ${buf.length}`, end);
|
||||
end = end >>> 0;
|
||||
validateInt32(end, 'end', 0, buf.length);
|
||||
}
|
||||
offset = offset >>> 0;
|
||||
if (offset >= end)
|
||||
return buf;
|
||||
}
|
||||
@@ -896,39 +885,37 @@ Buffer.prototype.write = function write(string, offset, length, encoding) {
|
||||
// Buffer#write(string);
|
||||
if (offset === undefined) {
|
||||
return this.utf8Write(string, 0, this.length);
|
||||
|
||||
}
|
||||
// Buffer#write(string, encoding)
|
||||
} else if (length === undefined && typeof offset === 'string') {
|
||||
if (length === undefined && typeof offset === 'string') {
|
||||
encoding = offset;
|
||||
length = this.length;
|
||||
offset = 0;
|
||||
|
||||
// Buffer#write(string, offset[, length][, encoding])
|
||||
} else if (isFinite(offset)) {
|
||||
offset = offset >>> 0;
|
||||
if (isFinite(length)) {
|
||||
length = length >>> 0;
|
||||
} else {
|
||||
if (offset === undefined) {
|
||||
offset = 0;
|
||||
} else {
|
||||
encoding = length;
|
||||
length = undefined;
|
||||
validateInt32(offset, 'offset', 0, this.length);
|
||||
}
|
||||
|
||||
const remaining = this.length - offset;
|
||||
if (length === undefined || length > remaining)
|
||||
length = remaining;
|
||||
|
||||
if (string.length > 0 && (length < 0 || offset < 0))
|
||||
throw new ERR_BUFFER_OUT_OF_BOUNDS();
|
||||
} else {
|
||||
// If someone is still calling the obsolete form of write(), tell them.
|
||||
// we don't want eg buf.write("foo", "utf8", 10) to silently turn into
|
||||
// buf.write("foo", "utf8"), so we can't ignore extra args
|
||||
throw new ERR_NO_LONGER_SUPPORTED(
|
||||
'Buffer.write(string, encoding, offset[, length])'
|
||||
);
|
||||
if (length === undefined) {
|
||||
length = remaining;
|
||||
} else if (typeof length === 'string') {
|
||||
encoding = length;
|
||||
length = remaining;
|
||||
} else {
|
||||
validateInt32(length, 'length', 0, this.length);
|
||||
if (length > remaining)
|
||||
length = remaining;
|
||||
}
|
||||
}
|
||||
|
||||
if (!encoding) return this.utf8Write(string, offset, length);
|
||||
if (!encoding)
|
||||
return this.utf8Write(string, offset, length);
|
||||
|
||||
encoding += '';
|
||||
switch (encoding.length) {
|
||||
|
||||
Reference in new issue
Block a user