From b64cb9aaf10b54fad8b718b15cfdec63547ba92b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Fri, 6 Sep 2019 12:09:57 -0400 Subject: [PATCH] fix: early return when instance is not iterable (#10396) * fix: early return when instance is not iterable * chore: update test fixtures * fix: gaurd against arguments for old browsers --- packages/babel-helpers/src/helpers.js | 7 ++++++- .../test/fixtures/destructuring/non-iterable/exec.js | 9 +++++++++ .../test/fixtures/regression/T7199/output.js | 2 +- .../preset-options/browserslist-defaults-2/output.js | 2 +- .../test/fixtures/sanity/block-scoping-for-of/output.js | 2 +- 5 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/non-iterable/exec.js diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index 29ed9d82264d..37485fdf705d 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -943,7 +943,9 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` // _e = _iteratorError // _i = _iterator // _s = _step - + if (!( + Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]" + )) { return } var _arr = []; var _n = true; var _d = false; @@ -969,6 +971,9 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` helpers.iterableToArrayLimitLoose = helper("7.0.0-beta.0")` export default function _iterableToArrayLimitLoose(arr, i) { + if (!( + Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]" + )) { return } var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/non-iterable/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/non-iterable/exec.js new file mode 100644 index 000000000000..83099c46c4f4 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/non-iterable/exec.js @@ -0,0 +1,9 @@ +expect( + () => { + var [foo, bar] = undefined; + }).toThrow("Invalid attempt to destructure non-iterable instance"); + +expect( + () => { + var foo = [ ...undefined ]; + }).toThrow("Invalid attempt to spread non-iterable instance"); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index 563d49889bff..cbe323d57d81 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -8,7 +8,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } diff --git a/packages/babel-preset-env/test/fixtures/preset-options/browserslist-defaults-2/output.js b/packages/babel-preset-env/test/fixtures/preset-options/browserslist-defaults-2/output.js index f894dda6a490..27a1db8f8775 100644 --- a/packages/babel-preset-env/test/fixtures/preset-options/browserslist-defaults-2/output.js +++ b/packages/babel-preset-env/test/fixtures/preset-options/browserslist-defaults-2/output.js @@ -4,7 +4,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } diff --git a/packages/babel-preset-env/test/fixtures/sanity/block-scoping-for-of/output.js b/packages/babel-preset-env/test/fixtures/sanity/block-scoping-for-of/output.js index 391887c3e15c..6fc0a62bd42f 100644 --- a/packages/babel-preset-env/test/fixtures/sanity/block-scoping-for-of/output.js +++ b/packages/babel-preset-env/test/fixtures/sanity/block-scoping-for-of/output.js @@ -2,7 +2,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }