+1
-1
| { | ||
| "name": "devalue", | ||
| "description": "Gets the job done when JSON.stringify can't", | ||
| "version": "5.8.0", | ||
| "version": "5.8.1", | ||
| "repository": "sveltejs/devalue", | ||
@@ -6,0 +6,0 @@ "sideEffects": false, |
+5
-0
@@ -8,1 +8,6 @@ export const UNDEFINED = -1; | ||
| export const SPARSE = -7; | ||
| // The largest valid value for a JavaScript array's `length` property, | ||
| // and the largest valid array index (one less than the max length). | ||
| export const MAX_ARRAY_LEN = 2 ** 32 - 1; | ||
| export const MAX_ARRAY_INDEX = MAX_ARRAY_LEN - 1; |
+18
-3
| import { decode64 } from './base64.js'; | ||
| import { | ||
| HOLE, | ||
| MAX_ARRAY_INDEX, | ||
| NAN, | ||
@@ -11,2 +12,3 @@ NEGATIVE_INFINITY, | ||
| } from './constants.js'; | ||
| import { is_valid_array_index, is_valid_array_len } from './utils.js'; | ||
@@ -223,13 +225,24 @@ /** | ||
| if (!Number.isInteger(len) || len < 0) { | ||
| if (!is_valid_array_len(len)) { | ||
| throw new Error('Invalid input'); | ||
| } | ||
| const array = new Array(len); | ||
| /** @type {any[]} */ | ||
| const array = []; | ||
| hydrated[index] = array; | ||
| // Setting `array.length = len` (or equivalently calling `new Array(len)`) | ||
| // on an untrusted `len` is a DoS vector: V8 eagerly allocates a | ||
| // contiguous backing store for array lengths below ~10^8, so a | ||
| // small payload with a huge declared length can force arbitrary | ||
| // memory allocation. Touching the largest-possible index first | ||
| // forces V8 into dictionary-elements mode, where `length` is | ||
| // just a number and no contiguous allocation occurs. | ||
| array[MAX_ARRAY_INDEX] = undefined; | ||
| delete array[MAX_ARRAY_INDEX]; | ||
| for (let i = 2; i < value.length; i += 2) { | ||
| const idx = value[i]; | ||
| if (!Number.isInteger(idx) || idx < 0 || idx >= len) { | ||
| if (!is_valid_array_index(idx) || idx >= len) { | ||
| throw new Error('Invalid input'); | ||
@@ -240,2 +253,4 @@ } | ||
| } | ||
| array.length = len; | ||
| } else { | ||
@@ -242,0 +257,0 @@ const array = new Array(value.length); |
+23
-7
@@ -0,1 +1,3 @@ | ||
| import { MAX_ARRAY_INDEX, MAX_ARRAY_LEN } from './constants.js'; | ||
| /** @type {Record<string, string>} */ | ||
@@ -116,4 +118,20 @@ export const escaped = { | ||
| /** @param {number} n */ | ||
| export function is_valid_array_index(n) { | ||
| if (!Number.isInteger(n)) return false; | ||
| if (n < 0) return false; | ||
| if (n > MAX_ARRAY_INDEX) return false; | ||
| return true; | ||
| } | ||
| /** @param {number} n */ | ||
| export function is_valid_array_len(n) { | ||
| if (!Number.isInteger(n)) return false; | ||
| if (n < 0) return false; | ||
| if (n > MAX_ARRAY_LEN) return false; | ||
| return true; | ||
| } | ||
| /** @param {string} s */ | ||
| function is_valid_array_index(s) { | ||
| function is_valid_array_index_string(s) { | ||
| if (s.length === 0) return false; | ||
@@ -125,7 +143,5 @@ if (s.length > 1 && s.charCodeAt(0) === 48) return false; // leading zero | ||
| } | ||
| // by this point we know it's a string of digits, but it has to be within the range of valid array indices | ||
| const n = +s; | ||
| if (n >= 2 ** 32 - 1) return false; | ||
| if (n < 0) return false; | ||
| return true; | ||
| // by this point we know it's a string of digits, but it has to be within | ||
| // the range of valid array indices | ||
| return is_valid_array_index(+s); | ||
| } | ||
@@ -140,3 +156,3 @@ | ||
| for (var i = keys.length - 1; i >= 0; i--) { | ||
| if (is_valid_array_index(keys[i])) { | ||
| if (is_valid_array_index_string(keys[i])) { | ||
| break; | ||
@@ -143,0 +159,0 @@ } |
@@ -24,4 +24,4 @@ { | ||
| ], | ||
| "mappings": ";;;;;iBAsBgBA,MAAMA;cCTTC,YAAYA;;;;;;;;;;;;;;iBCGTC,KAAKA;;;;;iBASLC,SAASA;;;;;iBCCTC,SAASA;;;;;iBAUHC,cAAcA", | ||
| "mappings": ";;;;;iBAsBgBA,MAAMA;cCPTC,YAAYA;;;;;;;;;;;;;;iBCGTC,KAAKA;;;;;iBASLC,SAASA;;;;;iBCDTC,SAASA;;;;;iBAUHC,cAAcA", | ||
| "ignoreList": [] | ||
| } |
52429
2.54%1380
2.22%