Skip to content

Commit aa372f7

Browse files
fix(utils): make isFormData detection logic stricter to avoid unnecessary calling of the toString method on the target; (#5661)
1 parent 0abc705 commit aa372f7

2 files changed

Lines changed: 40 additions & 5 deletions

File tree

‎lib/utils.js‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,16 @@ const isStream = (val) => isObject(val) && isFunction(val.pipe);
188188
* @returns {boolean} True if value is an FormData, otherwise false
189189
*/
190190
const isFormData = (thing) => {
191-
const pattern = '[object FormData]';
191+
let kind;
192192
return thing && (
193-
(typeof FormData === 'function' && thing instanceof FormData) ||
194-
toString.call(thing) === pattern ||
195-
(isFunction(thing.toString) && thing.toString() === pattern)
196-
);
193+
(typeof FormData === 'function' && thing instanceof FormData) || (
194+
isFunction(thing.append) && (
195+
(kind = kindOf(thing)) === 'formdata' ||
196+
// detect form-data instance
197+
(kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')
198+
)
199+
)
200+
)
197201
}
198202

199203
/**

‎test/unit/utils/utils.js‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,37 @@ describe('utils', function (){
2222
});
2323
assert.equal(utils.isFormData(new FormData()), true);
2424
});
25+
26+
it('should not call toString method on built-in objects instances', () => {
27+
const buf = Buffer.from('123');
28+
29+
buf.toString = () => assert.fail('should not be called');
30+
31+
assert.equal(utils.isFormData(buf), false);
32+
});
33+
34+
it('should not call toString method on built-in objects instances, even if append method exists', () => {
35+
const buf = Buffer.from('123');
36+
37+
buf.append = () => {};
38+
39+
buf.toString = () => assert.fail('should not be called');
40+
41+
assert.equal(utils.isFormData(buf), false);
42+
});
43+
44+
it('should detect custom FormData instances by toStringTag signature and append method presence', () => {
45+
class FormData {
46+
append(){
47+
48+
}
49+
50+
get [Symbol.toStringTag]() {
51+
return 'FormData';
52+
}
53+
}
54+
assert.equal(utils.isFormData(new FormData()), true);
55+
});
2556
});
2657

2758
describe('toJSON', function (){

0 commit comments

Comments
 (0)