Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit 6cbd89c

Browse files
vithdaviddias
authored andcommitted
fix: don't let qs mangle binary buffers (#569) (#570)
1 parent f2f1126 commit 6cbd89c

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

src/request-api.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
const Qs = require('qs')
4+
const qsDefaultEncoder = require('qs/lib/utils').encode
45
const isNode = require('detect-node')
56
const ndjson = require('ndjson')
67
const pump = require('pump')
@@ -112,7 +113,39 @@ function requestAPI (config, options, callback) {
112113
headers['Content-Type'] = `multipart/form-data; boundary=${stream.boundary}`
113114
}
114115

115-
const qs = Qs.stringify(options.qs, {arrayFormat: 'repeat'})
116+
const qs = Qs.stringify(options.qs, {
117+
arrayFormat: 'repeat',
118+
encoder: data => {
119+
// TODO: future releases of qs will provide the default
120+
// encoder as a 2nd argument to this function; it will
121+
// no longer be necessary to import qsDefaultEncoder
122+
if (Buffer.isBuffer(data)) {
123+
let uriEncoded = ''
124+
for (const byte of data) {
125+
// https://tools.ietf.org/html/rfc3986#page-14
126+
// ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E)
127+
if (
128+
(byte >= 0x41 && byte <= 0x5A) ||
129+
(byte >= 0x61 && byte <= 0x7A) ||
130+
(byte >= 0x30 && byte <= 0x39) ||
131+
(byte === 0x2D) ||
132+
(byte === 0x2E) ||
133+
(byte === 0x5F) ||
134+
(byte === 0x7E)
135+
) {
136+
uriEncoded += String.fromCharCode(byte)
137+
} else {
138+
const hex = byte.toString(16)
139+
// String.prototype.padStart() not widely supported yet
140+
const padded = hex.length === 1 ? `0${hex}` : hex
141+
uriEncoded += `%${padded}`
142+
}
143+
}
144+
return uriEncoded
145+
}
146+
return qsDefaultEncoder(data)
147+
}
148+
})
116149
const req = request(config.protocol)({
117150
hostname: config.host,
118151
path: `${config['api-path']}${options.path}?${qs}`,

0 commit comments

Comments
 (0)