|
2 | 2 |
|
3 | 3 | const { |
4 | 4 | ArrayFrom, |
| 5 | + MathMax, |
| 6 | + MathMin, |
5 | 7 | ObjectDefineProperty, |
6 | 8 | ObjectSetPrototypeOf, |
7 | 9 | PromiseResolve, |
@@ -41,21 +43,21 @@ const { |
41 | 43 | codes: { |
42 | 44 | ERR_INVALID_ARG_TYPE, |
43 | 45 | ERR_BUFFER_TOO_LARGE, |
44 | | - ERR_OUT_OF_RANGE, |
45 | 46 | } |
46 | 47 | } = require('internal/errors'); |
47 | 48 |
|
48 | 49 | const { |
49 | 50 | validateObject, |
50 | 51 | validateString, |
51 | | - validateUint32, |
52 | 52 | isUint32, |
53 | 53 | } = require('internal/validators'); |
54 | 54 |
|
55 | 55 | const kHandle = Symbol('kHandle'); |
56 | 56 | const kType = Symbol('kType'); |
57 | 57 | const kLength = Symbol('kLength'); |
58 | 58 |
|
| 59 | +const disallowedTypeCharacters = /[^\u{0020}-\u{007E}]/u; |
| 60 | + |
59 | 61 | let Buffer; |
60 | 62 |
|
61 | 63 | function lazyBuffer() { |
@@ -139,7 +141,7 @@ class Blob extends JSTransferable { |
139 | 141 | super(); |
140 | 142 | this[kHandle] = createBlob(sources_, length); |
141 | 143 | this[kLength] = length; |
142 | | - this[kType] = RegExpPrototypeTest(/[^\u{0020}-\u{007E}]/u, type) ? |
| 144 | + this[kType] = RegExpPrototypeTest(disallowedTypeCharacters, type) ? |
143 | 145 | '' : StringPrototypeToLowerCase(type); |
144 | 146 | } |
145 | 147 |
|
@@ -178,18 +180,32 @@ class Blob extends JSTransferable { |
178 | 180 |
|
179 | 181 | get size() { return this[kLength]; } |
180 | 182 |
|
181 | | - slice(start = 0, end = (this[kLength]), type = this[kType]) { |
182 | | - validateUint32(start, 'start'); |
183 | | - if (end < 0) end = this[kLength] + end; |
184 | | - validateUint32(end, 'end'); |
185 | | - validateString(type, 'type'); |
186 | | - if (end < start) |
187 | | - throw new ERR_OUT_OF_RANGE('end', 'greater than start', end); |
188 | | - if (end > this[kLength]) |
189 | | - throw new ERR_OUT_OF_RANGE('end', 'less than or equal to length', end); |
| 183 | + slice(start = 0, end = this[kLength], contentType = '') { |
| 184 | + if (start < 0) { |
| 185 | + start = MathMax(this[kLength] + start, 0); |
| 186 | + } else { |
| 187 | + start = MathMin(start, this[kLength]); |
| 188 | + } |
| 189 | + start |= 0; |
| 190 | + |
| 191 | + if (end < 0) { |
| 192 | + end = MathMax(this[kLength] + end, 0); |
| 193 | + } else { |
| 194 | + end = MathMin(end, this[kLength]); |
| 195 | + } |
| 196 | + end |= 0; |
| 197 | + |
| 198 | + contentType = `${contentType}`; |
| 199 | + if (RegExpPrototypeTest(disallowedTypeCharacters, contentType)) { |
| 200 | + contentType = ''; |
| 201 | + } else { |
| 202 | + contentType = StringPrototypeToLowerCase(contentType); |
| 203 | + } |
| 204 | + |
| 205 | + const span = MathMax(end - start, 0); |
| 206 | + |
190 | 207 | return new InternalBlob( |
191 | | - this[kHandle].slice(start, end), |
192 | | - end - start, type); |
| 208 | + this[kHandle].slice(start, start + span), span, contentType); |
193 | 209 | } |
194 | 210 |
|
195 | 211 | async arrayBuffer() { |
|
0 commit comments