@agnostack/verifyd 1.0.14-beta.1 → 1.0.14-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/lib/utils/rawbody.d.ts.map +1 -1
- package/dist/lib/utils/rawbody.js +6 -5
- package/dist/lib/utils/rawbody.js.map +1 -1
- package/dist/umd/lib/index.js +6 -368
- package/dist/umd/lib/index.js.map +1 -1
- package/dist/umd/lib/lib/utils/rawbody.d.ts.map +1 -1
- package/package.json +4 -5
- package/node_modules/bytes/History.md +0 -97
- package/node_modules/bytes/LICENSE +0 -23
- package/node_modules/bytes/Readme.md +0 -152
- package/node_modules/bytes/index.js +0 -170
- package/node_modules/bytes/package.json +0 -42
- package/node_modules/depd/History.md +0 -103
- package/node_modules/depd/LICENSE +0 -22
- package/node_modules/depd/Readme.md +0 -280
- package/node_modules/depd/index.js +0 -538
- package/node_modules/depd/lib/browser/index.js +0 -77
- package/node_modules/depd/package.json +0 -45
- package/node_modules/http-errors/HISTORY.md +0 -180
- package/node_modules/http-errors/LICENSE +0 -23
- package/node_modules/http-errors/README.md +0 -169
- package/node_modules/http-errors/index.js +0 -289
- package/node_modules/http-errors/package.json +0 -50
- package/node_modules/iconv-lite/Changelog.md +0 -162
- package/node_modules/iconv-lite/LICENSE +0 -21
- package/node_modules/iconv-lite/README.md +0 -156
- package/node_modules/iconv-lite/encodings/dbcs-codec.js +0 -555
- package/node_modules/iconv-lite/encodings/dbcs-data.js +0 -176
- package/node_modules/iconv-lite/encodings/index.js +0 -22
- package/node_modules/iconv-lite/encodings/internal.js +0 -188
- package/node_modules/iconv-lite/encodings/sbcs-codec.js +0 -72
- package/node_modules/iconv-lite/encodings/sbcs-data-generated.js +0 -451
- package/node_modules/iconv-lite/encodings/sbcs-data.js +0 -174
- package/node_modules/iconv-lite/encodings/tables/big5-added.json +0 -122
- package/node_modules/iconv-lite/encodings/tables/cp936.json +0 -264
- package/node_modules/iconv-lite/encodings/tables/cp949.json +0 -273
- package/node_modules/iconv-lite/encodings/tables/cp950.json +0 -177
- package/node_modules/iconv-lite/encodings/tables/eucjp.json +0 -182
- package/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +0 -1
- package/node_modules/iconv-lite/encodings/tables/gbk-added.json +0 -55
- package/node_modules/iconv-lite/encodings/tables/shiftjis.json +0 -125
- package/node_modules/iconv-lite/encodings/utf16.js +0 -177
- package/node_modules/iconv-lite/encodings/utf7.js +0 -290
- package/node_modules/iconv-lite/lib/bom-handling.js +0 -52
- package/node_modules/iconv-lite/lib/extend-node.js +0 -217
- package/node_modules/iconv-lite/lib/index.d.ts +0 -24
- package/node_modules/iconv-lite/lib/index.js +0 -153
- package/node_modules/iconv-lite/lib/streams.js +0 -121
- package/node_modules/iconv-lite/package.json +0 -46
- package/node_modules/inherits/LICENSE +0 -16
- package/node_modules/inherits/README.md +0 -42
- package/node_modules/inherits/inherits.js +0 -9
- package/node_modules/inherits/inherits_browser.js +0 -27
- package/node_modules/inherits/package.json +0 -29
- package/node_modules/raw-body/HISTORY.md +0 -308
- package/node_modules/raw-body/LICENSE +0 -22
- package/node_modules/raw-body/README.md +0 -223
- package/node_modules/raw-body/SECURITY.md +0 -24
- package/node_modules/raw-body/index.d.ts +0 -87
- package/node_modules/raw-body/index.js +0 -336
- package/node_modules/raw-body/package.json +0 -49
- package/node_modules/safer-buffer/LICENSE +0 -21
- package/node_modules/safer-buffer/Porting-Buffer.md +0 -268
- package/node_modules/safer-buffer/Readme.md +0 -156
- package/node_modules/safer-buffer/dangerous.js +0 -58
- package/node_modules/safer-buffer/package.json +0 -34
- package/node_modules/safer-buffer/safer.js +0 -77
- package/node_modules/safer-buffer/tests.js +0 -406
- package/node_modules/setprototypeof/LICENSE +0 -13
- package/node_modules/setprototypeof/README.md +0 -31
- package/node_modules/setprototypeof/index.d.ts +0 -2
- package/node_modules/setprototypeof/index.js +0 -17
- package/node_modules/setprototypeof/package.json +0 -38
- package/node_modules/setprototypeof/test/index.js +0 -24
- package/node_modules/statuses/HISTORY.md +0 -82
- package/node_modules/statuses/LICENSE +0 -23
- package/node_modules/statuses/README.md +0 -136
- package/node_modules/statuses/codes.json +0 -65
- package/node_modules/statuses/index.js +0 -146
- package/node_modules/statuses/package.json +0 -49
- package/node_modules/toidentifier/HISTORY.md +0 -9
- package/node_modules/toidentifier/LICENSE +0 -21
- package/node_modules/toidentifier/README.md +0 -61
- package/node_modules/toidentifier/index.js +0 -32
- package/node_modules/toidentifier/package.json +0 -38
- package/node_modules/unpipe/HISTORY.md +0 -4
- package/node_modules/unpipe/LICENSE +0 -22
- package/node_modules/unpipe/README.md +0 -43
- package/node_modules/unpipe/index.js +0 -69
- package/node_modules/unpipe/package.json +0 -27
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* raw-body
|
|
3
|
-
* Copyright(c) 2013-2014 Jonathan Ong
|
|
4
|
-
* Copyright(c) 2014-2022 Douglas Christopher Wilson
|
|
5
|
-
* MIT Licensed
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
'use strict'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Module dependencies.
|
|
12
|
-
* @private
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
var asyncHooks = tryRequireAsyncHooks()
|
|
16
|
-
var bytes = require('bytes')
|
|
17
|
-
var createError = require('http-errors')
|
|
18
|
-
var iconv = require('iconv-lite')
|
|
19
|
-
var unpipe = require('unpipe')
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Module exports.
|
|
23
|
-
* @public
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
module.exports = getRawBody
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Module variables.
|
|
30
|
-
* @private
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
var ICONV_ENCODING_MESSAGE_REGEXP = /^Encoding not recognized: /
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Get the decoder for a given encoding.
|
|
37
|
-
*
|
|
38
|
-
* @param {string} encoding
|
|
39
|
-
* @private
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
function getDecoder (encoding) {
|
|
43
|
-
if (!encoding) return null
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
return iconv.getDecoder(encoding)
|
|
47
|
-
} catch (e) {
|
|
48
|
-
// error getting decoder
|
|
49
|
-
if (!ICONV_ENCODING_MESSAGE_REGEXP.test(e.message)) throw e
|
|
50
|
-
|
|
51
|
-
// the encoding was not found
|
|
52
|
-
throw createError(415, 'specified encoding unsupported', {
|
|
53
|
-
encoding: encoding,
|
|
54
|
-
type: 'encoding.unsupported'
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get the raw body of a stream (typically HTTP).
|
|
61
|
-
*
|
|
62
|
-
* @param {object} stream
|
|
63
|
-
* @param {object|string|function} [options]
|
|
64
|
-
* @param {function} [callback]
|
|
65
|
-
* @public
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
function getRawBody (stream, options, callback) {
|
|
69
|
-
var done = callback
|
|
70
|
-
var opts = options || {}
|
|
71
|
-
|
|
72
|
-
// light validation
|
|
73
|
-
if (stream === undefined) {
|
|
74
|
-
throw new TypeError('argument stream is required')
|
|
75
|
-
} else if (typeof stream !== 'object' || stream === null || typeof stream.on !== 'function') {
|
|
76
|
-
throw new TypeError('argument stream must be a stream')
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (options === true || typeof options === 'string') {
|
|
80
|
-
// short cut for encoding
|
|
81
|
-
opts = {
|
|
82
|
-
encoding: options
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (typeof options === 'function') {
|
|
87
|
-
done = options
|
|
88
|
-
opts = {}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// validate callback is a function, if provided
|
|
92
|
-
if (done !== undefined && typeof done !== 'function') {
|
|
93
|
-
throw new TypeError('argument callback must be a function')
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// require the callback without promises
|
|
97
|
-
if (!done && !global.Promise) {
|
|
98
|
-
throw new TypeError('argument callback is required')
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// get encoding
|
|
102
|
-
var encoding = opts.encoding !== true
|
|
103
|
-
? opts.encoding
|
|
104
|
-
: 'utf-8'
|
|
105
|
-
|
|
106
|
-
// convert the limit to an integer
|
|
107
|
-
var limit = bytes.parse(opts.limit)
|
|
108
|
-
|
|
109
|
-
// convert the expected length to an integer
|
|
110
|
-
var length = opts.length != null && !isNaN(opts.length)
|
|
111
|
-
? parseInt(opts.length, 10)
|
|
112
|
-
: null
|
|
113
|
-
|
|
114
|
-
if (done) {
|
|
115
|
-
// classic callback style
|
|
116
|
-
return readStream(stream, encoding, length, limit, wrap(done))
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return new Promise(function executor (resolve, reject) {
|
|
120
|
-
readStream(stream, encoding, length, limit, function onRead (err, buf) {
|
|
121
|
-
if (err) return reject(err)
|
|
122
|
-
resolve(buf)
|
|
123
|
-
})
|
|
124
|
-
})
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Halt a stream.
|
|
129
|
-
*
|
|
130
|
-
* @param {Object} stream
|
|
131
|
-
* @private
|
|
132
|
-
*/
|
|
133
|
-
|
|
134
|
-
function halt (stream) {
|
|
135
|
-
// unpipe everything from the stream
|
|
136
|
-
unpipe(stream)
|
|
137
|
-
|
|
138
|
-
// pause stream
|
|
139
|
-
if (typeof stream.pause === 'function') {
|
|
140
|
-
stream.pause()
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Read the data from the stream.
|
|
146
|
-
*
|
|
147
|
-
* @param {object} stream
|
|
148
|
-
* @param {string} encoding
|
|
149
|
-
* @param {number} length
|
|
150
|
-
* @param {number} limit
|
|
151
|
-
* @param {function} callback
|
|
152
|
-
* @public
|
|
153
|
-
*/
|
|
154
|
-
|
|
155
|
-
function readStream (stream, encoding, length, limit, callback) {
|
|
156
|
-
var complete = false
|
|
157
|
-
var sync = true
|
|
158
|
-
|
|
159
|
-
// check the length and limit options.
|
|
160
|
-
// note: we intentionally leave the stream paused,
|
|
161
|
-
// so users should handle the stream themselves.
|
|
162
|
-
if (limit !== null && length !== null && length > limit) {
|
|
163
|
-
return done(createError(413, 'request entity too large', {
|
|
164
|
-
expected: length,
|
|
165
|
-
length: length,
|
|
166
|
-
limit: limit,
|
|
167
|
-
type: 'entity.too.large'
|
|
168
|
-
}))
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// streams1: assert request encoding is buffer.
|
|
172
|
-
// streams2+: assert the stream encoding is buffer.
|
|
173
|
-
// stream._decoder: streams1
|
|
174
|
-
// state.encoding: streams2
|
|
175
|
-
// state.decoder: streams2, specifically < 0.10.6
|
|
176
|
-
var state = stream._readableState
|
|
177
|
-
if (stream._decoder || (state && (state.encoding || state.decoder))) {
|
|
178
|
-
// developer error
|
|
179
|
-
return done(createError(500, 'stream encoding should not be set', {
|
|
180
|
-
type: 'stream.encoding.set'
|
|
181
|
-
}))
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (typeof stream.readable !== 'undefined' && !stream.readable) {
|
|
185
|
-
return done(createError(500, 'stream is not readable', {
|
|
186
|
-
type: 'stream.not.readable'
|
|
187
|
-
}))
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
var received = 0
|
|
191
|
-
var decoder
|
|
192
|
-
|
|
193
|
-
try {
|
|
194
|
-
decoder = getDecoder(encoding)
|
|
195
|
-
} catch (err) {
|
|
196
|
-
return done(err)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
var buffer = decoder
|
|
200
|
-
? ''
|
|
201
|
-
: []
|
|
202
|
-
|
|
203
|
-
// attach listeners
|
|
204
|
-
stream.on('aborted', onAborted)
|
|
205
|
-
stream.on('close', cleanup)
|
|
206
|
-
stream.on('data', onData)
|
|
207
|
-
stream.on('end', onEnd)
|
|
208
|
-
stream.on('error', onEnd)
|
|
209
|
-
|
|
210
|
-
// mark sync section complete
|
|
211
|
-
sync = false
|
|
212
|
-
|
|
213
|
-
function done () {
|
|
214
|
-
var args = new Array(arguments.length)
|
|
215
|
-
|
|
216
|
-
// copy arguments
|
|
217
|
-
for (var i = 0; i < args.length; i++) {
|
|
218
|
-
args[i] = arguments[i]
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// mark complete
|
|
222
|
-
complete = true
|
|
223
|
-
|
|
224
|
-
if (sync) {
|
|
225
|
-
process.nextTick(invokeCallback)
|
|
226
|
-
} else {
|
|
227
|
-
invokeCallback()
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function invokeCallback () {
|
|
231
|
-
cleanup()
|
|
232
|
-
|
|
233
|
-
if (args[0]) {
|
|
234
|
-
// halt the stream on error
|
|
235
|
-
halt(stream)
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
callback.apply(null, args)
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function onAborted () {
|
|
243
|
-
if (complete) return
|
|
244
|
-
|
|
245
|
-
done(createError(400, 'request aborted', {
|
|
246
|
-
code: 'ECONNABORTED',
|
|
247
|
-
expected: length,
|
|
248
|
-
length: length,
|
|
249
|
-
received: received,
|
|
250
|
-
type: 'request.aborted'
|
|
251
|
-
}))
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function onData (chunk) {
|
|
255
|
-
if (complete) return
|
|
256
|
-
|
|
257
|
-
received += chunk.length
|
|
258
|
-
|
|
259
|
-
if (limit !== null && received > limit) {
|
|
260
|
-
done(createError(413, 'request entity too large', {
|
|
261
|
-
limit: limit,
|
|
262
|
-
received: received,
|
|
263
|
-
type: 'entity.too.large'
|
|
264
|
-
}))
|
|
265
|
-
} else if (decoder) {
|
|
266
|
-
buffer += decoder.write(chunk)
|
|
267
|
-
} else {
|
|
268
|
-
buffer.push(chunk)
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
function onEnd (err) {
|
|
273
|
-
if (complete) return
|
|
274
|
-
if (err) return done(err)
|
|
275
|
-
|
|
276
|
-
if (length !== null && received !== length) {
|
|
277
|
-
done(createError(400, 'request size did not match content length', {
|
|
278
|
-
expected: length,
|
|
279
|
-
length: length,
|
|
280
|
-
received: received,
|
|
281
|
-
type: 'request.size.invalid'
|
|
282
|
-
}))
|
|
283
|
-
} else {
|
|
284
|
-
var string = decoder
|
|
285
|
-
? buffer + (decoder.end() || '')
|
|
286
|
-
: Buffer.concat(buffer)
|
|
287
|
-
done(null, string)
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
function cleanup () {
|
|
292
|
-
buffer = null
|
|
293
|
-
|
|
294
|
-
stream.removeListener('aborted', onAborted)
|
|
295
|
-
stream.removeListener('data', onData)
|
|
296
|
-
stream.removeListener('end', onEnd)
|
|
297
|
-
stream.removeListener('error', onEnd)
|
|
298
|
-
stream.removeListener('close', cleanup)
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Try to require async_hooks
|
|
304
|
-
* @private
|
|
305
|
-
*/
|
|
306
|
-
|
|
307
|
-
function tryRequireAsyncHooks () {
|
|
308
|
-
try {
|
|
309
|
-
return require('async_hooks')
|
|
310
|
-
} catch (e) {
|
|
311
|
-
return {}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Wrap function with async resource, if possible.
|
|
317
|
-
* AsyncResource.bind static method backported.
|
|
318
|
-
* @private
|
|
319
|
-
*/
|
|
320
|
-
|
|
321
|
-
function wrap (fn) {
|
|
322
|
-
var res
|
|
323
|
-
|
|
324
|
-
// create anonymous resource
|
|
325
|
-
if (asyncHooks.AsyncResource) {
|
|
326
|
-
res = new asyncHooks.AsyncResource(fn.name || 'bound-anonymous-fn')
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// incompatible node.js
|
|
330
|
-
if (!res || !res.runInAsyncScope) {
|
|
331
|
-
return fn
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// return bound function
|
|
335
|
-
return res.runInAsyncScope.bind(res, fn, null)
|
|
336
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "raw-body",
|
|
3
|
-
"description": "Get and validate the raw body of a readable stream.",
|
|
4
|
-
"version": "2.5.2",
|
|
5
|
-
"author": "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)",
|
|
6
|
-
"contributors": [
|
|
7
|
-
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
|
8
|
-
"Raynos <raynos2@gmail.com>"
|
|
9
|
-
],
|
|
10
|
-
"license": "MIT",
|
|
11
|
-
"repository": "stream-utils/raw-body",
|
|
12
|
-
"dependencies": {
|
|
13
|
-
"bytes": "3.1.2",
|
|
14
|
-
"http-errors": "2.0.0",
|
|
15
|
-
"iconv-lite": "0.4.24",
|
|
16
|
-
"unpipe": "1.0.0"
|
|
17
|
-
},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"bluebird": "3.7.2",
|
|
20
|
-
"eslint": "8.34.0",
|
|
21
|
-
"eslint-config-standard": "15.0.1",
|
|
22
|
-
"eslint-plugin-import": "2.27.5",
|
|
23
|
-
"eslint-plugin-markdown": "3.0.0",
|
|
24
|
-
"eslint-plugin-node": "11.1.0",
|
|
25
|
-
"eslint-plugin-promise": "6.1.1",
|
|
26
|
-
"eslint-plugin-standard": "4.1.0",
|
|
27
|
-
"mocha": "10.2.0",
|
|
28
|
-
"nyc": "15.1.0",
|
|
29
|
-
"readable-stream": "2.3.7",
|
|
30
|
-
"safe-buffer": "5.2.1"
|
|
31
|
-
},
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">= 0.8"
|
|
34
|
-
},
|
|
35
|
-
"files": [
|
|
36
|
-
"HISTORY.md",
|
|
37
|
-
"LICENSE",
|
|
38
|
-
"README.md",
|
|
39
|
-
"SECURITY.md",
|
|
40
|
-
"index.d.ts",
|
|
41
|
-
"index.js"
|
|
42
|
-
],
|
|
43
|
-
"scripts": {
|
|
44
|
-
"lint": "eslint .",
|
|
45
|
-
"test": "mocha --trace-deprecation --reporter spec --bail --check-leaks test/",
|
|
46
|
-
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
|
|
47
|
-
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2018 Nikita Skovoroda <chalkerx@gmail.com>
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
# Porting to the Buffer.from/Buffer.alloc API
|
|
2
|
-
|
|
3
|
-
<a id="overview"></a>
|
|
4
|
-
## Overview
|
|
5
|
-
|
|
6
|
-
- [Variant 1: Drop support for Node.js ≤ 4.4.x and 5.0.0 — 5.9.x.](#variant-1) (*recommended*)
|
|
7
|
-
- [Variant 2: Use a polyfill](#variant-2)
|
|
8
|
-
- [Variant 3: manual detection, with safeguards](#variant-3)
|
|
9
|
-
|
|
10
|
-
### Finding problematic bits of code using grep
|
|
11
|
-
|
|
12
|
-
Just run `grep -nrE '[^a-zA-Z](Slow)?Buffer\s*\(' --exclude-dir node_modules`.
|
|
13
|
-
|
|
14
|
-
It will find all the potentially unsafe places in your own code (with some considerably unlikely
|
|
15
|
-
exceptions).
|
|
16
|
-
|
|
17
|
-
### Finding problematic bits of code using Node.js 8
|
|
18
|
-
|
|
19
|
-
If you’re using Node.js ≥ 8.0.0 (which is recommended), Node.js exposes multiple options that help with finding the relevant pieces of code:
|
|
20
|
-
|
|
21
|
-
- `--trace-warnings` will make Node.js show a stack trace for this warning and other warnings that are printed by Node.js.
|
|
22
|
-
- `--trace-deprecation` does the same thing, but only for deprecation warnings.
|
|
23
|
-
- `--pending-deprecation` will show more types of deprecation warnings. In particular, it will show the `Buffer()` deprecation warning, even on Node.js 8.
|
|
24
|
-
|
|
25
|
-
You can set these flags using an environment variable:
|
|
26
|
-
|
|
27
|
-
```console
|
|
28
|
-
$ export NODE_OPTIONS='--trace-warnings --pending-deprecation'
|
|
29
|
-
$ cat example.js
|
|
30
|
-
'use strict';
|
|
31
|
-
const foo = new Buffer('foo');
|
|
32
|
-
$ node example.js
|
|
33
|
-
(node:7147) [DEP0005] DeprecationWarning: The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead.
|
|
34
|
-
at showFlaggedDeprecation (buffer.js:127:13)
|
|
35
|
-
at new Buffer (buffer.js:148:3)
|
|
36
|
-
at Object.<anonymous> (/path/to/example.js:2:13)
|
|
37
|
-
[... more stack trace lines ...]
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### Finding problematic bits of code using linters
|
|
41
|
-
|
|
42
|
-
Eslint rules [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
|
43
|
-
or
|
|
44
|
-
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
|
45
|
-
also find calls to deprecated `Buffer()` API. Those rules are included in some pre-sets.
|
|
46
|
-
|
|
47
|
-
There is a drawback, though, that it doesn't always
|
|
48
|
-
[work correctly](https://github.com/chalker/safer-buffer#why-not-safe-buffer) when `Buffer` is
|
|
49
|
-
overriden e.g. with a polyfill, so recommended is a combination of this and some other method
|
|
50
|
-
described above.
|
|
51
|
-
|
|
52
|
-
<a id="variant-1"></a>
|
|
53
|
-
## Variant 1: Drop support for Node.js ≤ 4.4.x and 5.0.0 — 5.9.x.
|
|
54
|
-
|
|
55
|
-
This is the recommended solution nowadays that would imply only minimal overhead.
|
|
56
|
-
|
|
57
|
-
The Node.js 5.x release line has been unsupported since July 2016, and the Node.js 4.x release line reaches its End of Life in April 2018 (→ [Schedule](https://github.com/nodejs/Release#release-schedule)). This means that these versions of Node.js will *not* receive any updates, even in case of security issues, so using these release lines should be avoided, if at all possible.
|
|
58
|
-
|
|
59
|
-
What you would do in this case is to convert all `new Buffer()` or `Buffer()` calls to use `Buffer.alloc()` or `Buffer.from()`, in the following way:
|
|
60
|
-
|
|
61
|
-
- For `new Buffer(number)`, replace it with `Buffer.alloc(number)`.
|
|
62
|
-
- For `new Buffer(string)` (or `new Buffer(string, encoding)`), replace it with `Buffer.from(string)` (or `Buffer.from(string, encoding)`).
|
|
63
|
-
- For all other combinations of arguments (these are much rarer), also replace `new Buffer(...arguments)` with `Buffer.from(...arguments)`.
|
|
64
|
-
|
|
65
|
-
Note that `Buffer.alloc()` is also _faster_ on the current Node.js versions than
|
|
66
|
-
`new Buffer(size).fill(0)`, which is what you would otherwise need to ensure zero-filling.
|
|
67
|
-
|
|
68
|
-
Enabling eslint rule [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
|
69
|
-
or
|
|
70
|
-
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
|
71
|
-
is recommended to avoid accidential unsafe Buffer API usage.
|
|
72
|
-
|
|
73
|
-
There is also a [JSCodeshift codemod](https://github.com/joyeecheung/node-dep-codemod#dep005)
|
|
74
|
-
for automatically migrating Buffer constructors to `Buffer.alloc()` or `Buffer.from()`.
|
|
75
|
-
Note that it currently only works with cases where the arguments are literals or where the
|
|
76
|
-
constructor is invoked with two arguments.
|
|
77
|
-
|
|
78
|
-
_If you currently support those older Node.js versions and dropping them would be a semver-major change
|
|
79
|
-
for you, or if you support older branches of your packages, consider using [Variant 2](#variant-2)
|
|
80
|
-
or [Variant 3](#variant-3) on older branches, so people using those older branches will also receive
|
|
81
|
-
the fix. That way, you will eradicate potential issues caused by unguarded Buffer API usage and
|
|
82
|
-
your users will not observe a runtime deprecation warning when running your code on Node.js 10._
|
|
83
|
-
|
|
84
|
-
<a id="variant-2"></a>
|
|
85
|
-
## Variant 2: Use a polyfill
|
|
86
|
-
|
|
87
|
-
Utilize [safer-buffer](https://www.npmjs.com/package/safer-buffer) as a polyfill to support older
|
|
88
|
-
Node.js versions.
|
|
89
|
-
|
|
90
|
-
You would take exacly the same steps as in [Variant 1](#variant-1), but with a polyfill
|
|
91
|
-
`const Buffer = require('safer-buffer').Buffer` in all files where you use the new `Buffer` api.
|
|
92
|
-
|
|
93
|
-
Make sure that you do not use old `new Buffer` API — in any files where the line above is added,
|
|
94
|
-
using old `new Buffer()` API will _throw_. It will be easy to notice that in CI, though.
|
|
95
|
-
|
|
96
|
-
Alternatively, you could use [buffer-from](https://www.npmjs.com/package/buffer-from) and/or
|
|
97
|
-
[buffer-alloc](https://www.npmjs.com/package/buffer-alloc) [ponyfills](https://ponyfill.com/) —
|
|
98
|
-
those are great, the only downsides being 4 deps in the tree and slightly more code changes to
|
|
99
|
-
migrate off them (as you would be using e.g. `Buffer.from` under a different name). If you need only
|
|
100
|
-
`Buffer.from` polyfilled — `buffer-from` alone which comes with no extra dependencies.
|
|
101
|
-
|
|
102
|
-
_Alternatively, you could use [safe-buffer](https://www.npmjs.com/package/safe-buffer) — it also
|
|
103
|
-
provides a polyfill, but takes a different approach which has
|
|
104
|
-
[it's drawbacks](https://github.com/chalker/safer-buffer#why-not-safe-buffer). It will allow you
|
|
105
|
-
to also use the older `new Buffer()` API in your code, though — but that's arguably a benefit, as
|
|
106
|
-
it is problematic, can cause issues in your code, and will start emitting runtime deprecation
|
|
107
|
-
warnings starting with Node.js 10._
|
|
108
|
-
|
|
109
|
-
Note that in either case, it is important that you also remove all calls to the old Buffer
|
|
110
|
-
API manually — just throwing in `safe-buffer` doesn't fix the problem by itself, it just provides
|
|
111
|
-
a polyfill for the new API. I have seen people doing that mistake.
|
|
112
|
-
|
|
113
|
-
Enabling eslint rule [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
|
114
|
-
or
|
|
115
|
-
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
|
116
|
-
is recommended.
|
|
117
|
-
|
|
118
|
-
_Don't forget to drop the polyfill usage once you drop support for Node.js < 4.5.0._
|
|
119
|
-
|
|
120
|
-
<a id="variant-3"></a>
|
|
121
|
-
## Variant 3 — manual detection, with safeguards
|
|
122
|
-
|
|
123
|
-
This is useful if you create Buffer instances in only a few places (e.g. one), or you have your own
|
|
124
|
-
wrapper around them.
|
|
125
|
-
|
|
126
|
-
### Buffer(0)
|
|
127
|
-
|
|
128
|
-
This special case for creating empty buffers can be safely replaced with `Buffer.concat([])`, which
|
|
129
|
-
returns the same result all the way down to Node.js 0.8.x.
|
|
130
|
-
|
|
131
|
-
### Buffer(notNumber)
|
|
132
|
-
|
|
133
|
-
Before:
|
|
134
|
-
|
|
135
|
-
```js
|
|
136
|
-
var buf = new Buffer(notNumber, encoding);
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
After:
|
|
140
|
-
|
|
141
|
-
```js
|
|
142
|
-
var buf;
|
|
143
|
-
if (Buffer.from && Buffer.from !== Uint8Array.from) {
|
|
144
|
-
buf = Buffer.from(notNumber, encoding);
|
|
145
|
-
} else {
|
|
146
|
-
if (typeof notNumber === 'number')
|
|
147
|
-
throw new Error('The "size" argument must be of type number.');
|
|
148
|
-
buf = new Buffer(notNumber, encoding);
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
`encoding` is optional.
|
|
153
|
-
|
|
154
|
-
Note that the `typeof notNumber` before `new Buffer` is required (for cases when `notNumber` argument is not
|
|
155
|
-
hard-coded) and _is not caused by the deprecation of Buffer constructor_ — it's exactly _why_ the
|
|
156
|
-
Buffer constructor is deprecated. Ecosystem packages lacking this type-check caused numereous
|
|
157
|
-
security issues — situations when unsanitized user input could end up in the `Buffer(arg)` create
|
|
158
|
-
problems ranging from DoS to leaking sensitive information to the attacker from the process memory.
|
|
159
|
-
|
|
160
|
-
When `notNumber` argument is hardcoded (e.g. literal `"abc"` or `[0,1,2]`), the `typeof` check can
|
|
161
|
-
be omitted.
|
|
162
|
-
|
|
163
|
-
Also note that using TypeScript does not fix this problem for you — when libs written in
|
|
164
|
-
`TypeScript` are used from JS, or when user input ends up there — it behaves exactly as pure JS, as
|
|
165
|
-
all type checks are translation-time only and are not present in the actual JS code which TS
|
|
166
|
-
compiles to.
|
|
167
|
-
|
|
168
|
-
### Buffer(number)
|
|
169
|
-
|
|
170
|
-
For Node.js 0.10.x (and below) support:
|
|
171
|
-
|
|
172
|
-
```js
|
|
173
|
-
var buf;
|
|
174
|
-
if (Buffer.alloc) {
|
|
175
|
-
buf = Buffer.alloc(number);
|
|
176
|
-
} else {
|
|
177
|
-
buf = new Buffer(number);
|
|
178
|
-
buf.fill(0);
|
|
179
|
-
}
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Otherwise (Node.js ≥ 0.12.x):
|
|
183
|
-
|
|
184
|
-
```js
|
|
185
|
-
const buf = Buffer.alloc ? Buffer.alloc(number) : new Buffer(number).fill(0);
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Regarding Buffer.allocUnsafe
|
|
189
|
-
|
|
190
|
-
Be extra cautious when using `Buffer.allocUnsafe`:
|
|
191
|
-
* Don't use it if you don't have a good reason to
|
|
192
|
-
* e.g. you probably won't ever see a performance difference for small buffers, in fact, those
|
|
193
|
-
might be even faster with `Buffer.alloc()`,
|
|
194
|
-
* if your code is not in the hot code path — you also probably won't notice a difference,
|
|
195
|
-
* keep in mind that zero-filling minimizes the potential risks.
|
|
196
|
-
* If you use it, make sure that you never return the buffer in a partially-filled state,
|
|
197
|
-
* if you are writing to it sequentially — always truncate it to the actuall written length
|
|
198
|
-
|
|
199
|
-
Errors in handling buffers allocated with `Buffer.allocUnsafe` could result in various issues,
|
|
200
|
-
ranged from undefined behaviour of your code to sensitive data (user input, passwords, certs)
|
|
201
|
-
leaking to the remote attacker.
|
|
202
|
-
|
|
203
|
-
_Note that the same applies to `new Buffer` usage without zero-filling, depending on the Node.js
|
|
204
|
-
version (and lacking type checks also adds DoS to the list of potential problems)._
|
|
205
|
-
|
|
206
|
-
<a id="faq"></a>
|
|
207
|
-
## FAQ
|
|
208
|
-
|
|
209
|
-
<a id="design-flaws"></a>
|
|
210
|
-
### What is wrong with the `Buffer` constructor?
|
|
211
|
-
|
|
212
|
-
The `Buffer` constructor could be used to create a buffer in many different ways:
|
|
213
|
-
|
|
214
|
-
- `new Buffer(42)` creates a `Buffer` of 42 bytes. Before Node.js 8, this buffer contained
|
|
215
|
-
*arbitrary memory* for performance reasons, which could include anything ranging from
|
|
216
|
-
program source code to passwords and encryption keys.
|
|
217
|
-
- `new Buffer('abc')` creates a `Buffer` that contains the UTF-8-encoded version of
|
|
218
|
-
the string `'abc'`. A second argument could specify another encoding: For example,
|
|
219
|
-
`new Buffer(string, 'base64')` could be used to convert a Base64 string into the original
|
|
220
|
-
sequence of bytes that it represents.
|
|
221
|
-
- There are several other combinations of arguments.
|
|
222
|
-
|
|
223
|
-
This meant that, in code like `var buffer = new Buffer(foo);`, *it is not possible to tell
|
|
224
|
-
what exactly the contents of the generated buffer are* without knowing the type of `foo`.
|
|
225
|
-
|
|
226
|
-
Sometimes, the value of `foo` comes from an external source. For example, this function
|
|
227
|
-
could be exposed as a service on a web server, converting a UTF-8 string into its Base64 form:
|
|
228
|
-
|
|
229
|
-
```
|
|
230
|
-
function stringToBase64(req, res) {
|
|
231
|
-
// The request body should have the format of `{ string: 'foobar' }`
|
|
232
|
-
const rawBytes = new Buffer(req.body.string)
|
|
233
|
-
const encoded = rawBytes.toString('base64')
|
|
234
|
-
res.end({ encoded: encoded })
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
Note that this code does *not* validate the type of `req.body.string`:
|
|
239
|
-
|
|
240
|
-
- `req.body.string` is expected to be a string. If this is the case, all goes well.
|
|
241
|
-
- `req.body.string` is controlled by the client that sends the request.
|
|
242
|
-
- If `req.body.string` is the *number* `50`, the `rawBytes` would be 50 bytes:
|
|
243
|
-
- Before Node.js 8, the content would be uninitialized
|
|
244
|
-
- After Node.js 8, the content would be `50` bytes with the value `0`
|
|
245
|
-
|
|
246
|
-
Because of the missing type check, an attacker could intentionally send a number
|
|
247
|
-
as part of the request. Using this, they can either:
|
|
248
|
-
|
|
249
|
-
- Read uninitialized memory. This **will** leak passwords, encryption keys and other
|
|
250
|
-
kinds of sensitive information. (Information leak)
|
|
251
|
-
- Force the program to allocate a large amount of memory. For example, when specifying
|
|
252
|
-
`500000000` as the input value, each request will allocate 500MB of memory.
|
|
253
|
-
This can be used to either exhaust the memory available of a program completely
|
|
254
|
-
and make it crash, or slow it down significantly. (Denial of Service)
|
|
255
|
-
|
|
256
|
-
Both of these scenarios are considered serious security issues in a real-world
|
|
257
|
-
web server context.
|
|
258
|
-
|
|
259
|
-
when using `Buffer.from(req.body.string)` instead, passing a number will always
|
|
260
|
-
throw an exception instead, giving a controlled behaviour that can always be
|
|
261
|
-
handled by the program.
|
|
262
|
-
|
|
263
|
-
<a id="ecosystem-usage"></a>
|
|
264
|
-
### The `Buffer()` constructor has been deprecated for a while. Is this really an issue?
|
|
265
|
-
|
|
266
|
-
Surveys of code in the `npm` ecosystem have shown that the `Buffer()` constructor is still
|
|
267
|
-
widely used. This includes new code, and overall usage of such code has actually been
|
|
268
|
-
*increasing*.
|