Fix many JS vulns, fix tests (#1775)

* fix: lint problem

* fix: ignore malformed JSON file for FlowJS

* fix: add missing @types/jest package

* chore: update TypeScript version

* chore: update all eslint deps

Includes updating and installing missing/wrong peer deps

* chore: update all Jest deps

* chore: replace Jest config with jest.config.ts

* fix: make root Jest tests ignore Example folders

* chore: update css-select dep

* chore: update css-tree to latest 1.x version

2.x broke tests so left a 1.x

* chore: upgrade ansi-regex to close JS vuln

* chore: upgrade ejs to close JS vuln

* chore: upgrade async to close JS vuln

* chore: upgrade simple-plist to close JS vuln
This commit is contained in:
Stephen Pittman
2022-07-15 00:25:55 +10:00
committed by GitHub
parent 1dc42ea8a8
commit 2a44346049
16 changed files with 1689 additions and 1643 deletions
+1
View File
@@ -1,4 +1,5 @@
[ignore] [ignore]
.*/node_modules/resolve/test/resolver/malformed_package_json/package.json
[include] [include]
+9
View File
@@ -0,0 +1,9 @@
import { Config } from '@jest/types';
const config: Config.InitialOptions = {
testPathIgnorePatterns: ['/node_modules/', '/Example/', '/TestsExample/'],
preset: 'react-native',
verbose: true,
};
export default config;
+18 -15
View File
@@ -59,36 +59,39 @@
"react-native": ">=0.50.0" "react-native": ">=0.50.0"
}, },
"dependencies": { "dependencies": {
"css-select": "^4.2.1", "css-select": "^5.1.0",
"css-tree": "^1.0.0-alpha.39" "css-tree": "^1.1.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.18.2",
"@babel/plugin-syntax-flow": "^7.17.12",
"@babel/plugin-transform-react-jsx": "^7.17.12",
"@react-native-community/bob": "^0.9.7", "@react-native-community/bob": "^0.9.7",
"@react-native-community/eslint-config": "0.0.7", "@react-native-community/eslint-config": "^3.0.2",
"@react-native-community/eslint-plugin": "^1.0.0", "@react-native-community/eslint-plugin": "^1.2.0",
"@types/css-tree": "^1.0.3", "@types/css-tree": "^1.0.3",
"@types/jest": "^27.5.2",
"@types/node": "*",
"@types/react": "^17.0.16", "@types/react": "^17.0.16",
"@types/react-native": "^0.63.40", "@types/react-native": "^0.63.40",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"babel-jest": "^25.1.0", "babel-jest": "^28.1.0",
"eslint": "^6.8.0", "eslint": "^8.16.0",
"eslint-plugin-flowtype": "^4.6.0", "eslint-plugin-flowtype": "^8.0.3",
"eslint-plugin-prettier": "^3.1.2", "eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.18.3", "eslint-plugin-react": "^7.30.0",
"flow-bin": "^0.119.1", "flow-bin": "^0.119.1",
"flow-typed": "^3.0.0", "flow-typed": "^3.0.0",
"flowgen": "^1.10.0", "flowgen": "^1.10.0",
"jest": "^25.1.0", "jest": "^28.1.0",
"pegjs": "^0.10.0", "pegjs": "^0.10.0",
"prettier": "^1.19.1", "prettier": "^2.6.2",
"react": "^16.13.0", "react": "^16.13.0",
"react-native": "^0.62.3", "react-native": "^0.62.3",
"react-test-renderer": "^16.13.0", "react-test-renderer": "^16.13.0",
"release-it": "^14.12.5", "release-it": "^14.12.5",
"typescript": "^3.8.3" "ts-node": "^10.8.0",
}, "typescript": "^4.7.2"
"jest": {
"preset": "react-native"
}, },
"nativePackage": true "nativePackage": true
} }
+1 -1
View File
@@ -227,7 +227,7 @@ function remeasure() {
export class WebShape< export class WebShape<
P extends BaseProps = BaseProps, P extends BaseProps = BaseProps,
C = {} C = {},
> extends React.Component<P, C> { > extends React.Component<P, C> {
[x: string]: unknown; [x: string]: unknown;
_remeasureMetricsOnActivation: () => void; _remeasureMetricsOnActivation: () => void;
+11 -12
View File
@@ -117,7 +117,7 @@ function existsOne(
elems: Array<XmlAST | string>, elems: Array<XmlAST | string>,
): boolean { ): boolean {
return elems.some( return elems.some(
elem => (elem) =>
typeof elem === 'object' && typeof elem === 'object' &&
(predicate(elem) || existsOne(predicate, elem.children)), (predicate(elem) || existsOne(predicate, elem.children)),
); );
@@ -290,7 +290,7 @@ function filterByPseudos(selectors: FlatSelectorList) {
csstree.generate({ csstree.generate({
type: 'Selector', type: 'Selector',
children: new List<CssNode>().fromArray( children: new List<CssNode>().fromArray(
pseudos.map(pseudo => pseudo.item.data), pseudos.map((pseudo) => pseudo.item.data),
), ),
}), }),
), ),
@@ -307,7 +307,7 @@ const usePseudos = [''];
*/ */
function cleanPseudos(selectors: FlatSelectorList) { function cleanPseudos(selectors: FlatSelectorList) {
selectors.forEach(({ pseudos }) => selectors.forEach(({ pseudos }) =>
pseudos.forEach(pseudo => pseudo.list.remove(pseudo.item)), pseudos.forEach((pseudo) => pseudo.list.remove(pseudo.item)),
); );
} }
@@ -493,7 +493,7 @@ function sortSelectors(selectors: FlatSelectorList) {
return selectors; return selectors;
} }
const specs = selectors.map(selectorWithSpecificity); const specs = selectors.map(selectorWithSpecificity);
return exec(specs, len).map(s => s.selector); return exec(specs, len).map((s) => s.selector);
} }
const declarationParseProps = { const declarationParseProps = {
@@ -517,14 +517,17 @@ function CSSStyleDeclaration(ast: XmlAST) {
styles, styles,
declarationParseProps, declarationParseProps,
) as DeclarationList; ) as DeclarationList;
declarations.children.each(node => { declarations.children.each((node) => {
try { try {
const { property, value, important } = node as Declaration; const { property, value, important } = node as Declaration;
const name = property.trim(); const name = property.trim();
priority.set(name, important); priority.set(name, important);
style[camelCase(name)] = csstree.generate(value).trim(); style[camelCase(name)] = csstree.generate(value).trim();
} catch (styleError) { } catch (styleError) {
if (styleError.message !== 'Unknown node type: undefined') { if (
styleError instanceof Error &&
styleError.message !== 'Unknown node type: undefined'
) {
console.warn( console.warn(
"Warning: Parse error when parsing inline styles, style properties of this element cannot be used. The raw styles can still be get/set using .attr('style').value. Error details: " + "Warning: Parse error when parsing inline styles, style properties of this element cannot be used. The raw styles can still be get/set using .attr('style').value. Error details: " +
styleError, styleError,
@@ -666,7 +669,7 @@ export const inlineStyles: Middleware = function inlineStyles(
}, },
}); });
} catch (selectError) { } catch (selectError) {
if (selectError.constructor === SyntaxError) { if (selectError instanceof SyntaxError) {
console.warn( console.warn(
'Warning: Syntax error when trying to select \n\n' + 'Warning: Syntax error when trying to select \n\n' +
selectorStr + selectorStr +
@@ -695,11 +698,7 @@ export function SvgCssUri(props: UriProps) {
const { uri, onError = err } = props; const { uri, onError = err } = props;
const [xml, setXml] = useState<string | null>(null); const [xml, setXml] = useState<string | null>(null);
useEffect(() => { useEffect(() => {
uri uri ? fetchText(uri).then(setXml).catch(onError) : setXml(null);
? fetchText(uri)
.then(setXml)
.catch(onError)
: setXml(null);
}, [onError, uri]); }, [onError, uri]);
return <SvgCss xml={xml} override={props} />; return <SvgCss xml={xml} override={props} />;
} }
+6 -2
View File
@@ -252,8 +252,12 @@ export default class Shape<P> extends Component<P> {
* representative example / reproduction. * representative example / reproduction.
* */ * */
getBBox = (options?: SVGBoundingBoxOptions): SVGRect => { getBBox = (options?: SVGBoundingBoxOptions): SVGRect => {
const { fill = true, stroke = true, markers = true, clipped = true } = const {
options || {}; fill = true,
stroke = true,
markers = true,
clipped = true,
} = options || {};
const handle = findNodeHandle(this.root as Component); const handle = findNodeHandle(this.root as Component);
return RNSVGRenderableManager.getBBox(handle, { return RNSVGRenderableManager.getBBox(handle, {
fill, fill,
+1 -6
View File
@@ -5,12 +5,7 @@
const DEG_TO_RAD = Math.PI / 180; const DEG_TO_RAD = Math.PI / 180;
export const identity: [number, number, number, number, number, number] = [ export const identity: [number, number, number, number, number, number] = [
1, 1, 0, 0, 1, 0, 0,
0,
0,
1,
0,
0,
]; ];
let a = 1; let a = 1;
+1 -1
View File
@@ -117,7 +117,7 @@ const SvgTouchableMixin = {
}; };
const touchKeys = Object.keys(SvgTouchableMixin); const touchKeys = Object.keys(SvgTouchableMixin);
const touchVals = touchKeys.map(key => SvgTouchableMixin[key]); const touchVals = touchKeys.map((key) => SvgTouchableMixin[key]);
const numTouchKeys = touchKeys.length; const numTouchKeys = touchKeys.length;
export default (target: { [x: string]: unknown; state: unknown }) => { export default (target: { [x: string]: unknown; state: unknown }) => {
-1
View File
@@ -7,7 +7,6 @@ const contextFillBrush = [3];
const contextStrokeBrush = [4]; const contextStrokeBrush = [4];
export default function extractBrush(color?: ColorValue) { export default function extractBrush(color?: ColorValue) {
if (!color || color === 'none') { if (!color || color === 'none') {
return null; return null;
} }
+1 -1
View File
@@ -54,7 +54,7 @@ export default function extractGradient(
const stops = []; const stops = [];
const childArray = children const childArray = children
? Children.map(children, child => ? Children.map(children, (child) =>
React.cloneElement(child, { React.cloneElement(child, {
parent, parent,
}), }),
+1 -4
View File
@@ -11,10 +11,7 @@ export default function extractLengthList(
} else if (typeof lengthList === 'number') { } else if (typeof lengthList === 'number') {
return [lengthList]; return [lengthList];
} else if (typeof lengthList === 'string') { } else if (typeof lengthList === 'string') {
return lengthList return lengthList.trim().replace(commaReg, ' ').split(spaceReg);
.trim()
.replace(commaReg, ' ')
.split(spaceReg);
} else { } else {
return []; return [];
} }
+2 -1
View File
@@ -3,7 +3,8 @@ import extractLengthList from './extractLengthList';
import { pickNotNil } from '../util'; import { pickNotNil } from '../util';
import { NumberArray, NumberProp } from './types'; import { NumberArray, NumberProp } from './types';
const fontRegExp = /^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?(?:%|px|em|pt|pc|mm|cm|in]))*(?:\s*\/.*?)?\s+)?\s*"?([^"]*)/i; const fontRegExp =
/^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?(?:%|px|em|pt|pc|mm|cm|in]))*(?:\s*\/.*?)?\s+)?\s*"?([^"]*)/i;
const fontFamilyPrefix = /^[\s"']*/; const fontFamilyPrefix = /^[\s"']*/;
const fontFamilySuffix = /[\s"']*$/; const fontFamilySuffix = /[\s"']*$/;
const commaReg = /\s*,\s*/g; const commaReg = /\s*,\s*/g;
+2 -11
View File
@@ -3,17 +3,8 @@ import { parse } from './transform';
import { NumberProp, TransformedProps, TransformProps } from './types'; import { NumberProp, TransformedProps, TransformProps } from './types';
function appendTransformProps(props: TransformedProps) { function appendTransformProps(props: TransformedProps) {
const { const { x, y, originX, originY, scaleX, scaleY, rotation, skewX, skewY } =
x, props;
y,
originX,
originY,
scaleX,
scaleY,
rotation,
skewX,
skewY,
} = props;
appendTransform( appendTransform(
x + originX, x + originX,
y + originY, y + originY,
+2 -3
View File
@@ -36,9 +36,8 @@ export default function extractViewBox(props: {
return null; return null;
} }
const params = (Array.isArray(viewBox) const params = (
? viewBox Array.isArray(viewBox) ? viewBox : viewBox.trim().split(spacesRegExp)
: viewBox.trim().split(spacesRegExp)
).map(Number); ).map(Number);
if (params.length !== 4 || params.some(isNaN)) { if (params.length !== 4 || params.some(isNaN)) {
+5 -8
View File
@@ -110,9 +110,10 @@ export const err = console.error.bind(console);
export function SvgXml(props: XmlProps) { export function SvgXml(props: XmlProps) {
const { onError = err, xml, override } = props; const { onError = err, xml, override } = props;
const ast = useMemo<JsxAST | null>(() => (xml !== null ? parse(xml) : null), [ const ast = useMemo<JsxAST | null>(
xml, () => (xml !== null ? parse(xml) : null),
]); [xml],
);
try { try {
return <SvgAst ast={ast} override={override || props} />; return <SvgAst ast={ast} override={override || props} />;
@@ -134,11 +135,7 @@ export function SvgUri(props: UriProps) {
const { onError = err, uri } = props; const { onError = err, uri } = props;
const [xml, setXml] = useState<string | null>(null); const [xml, setXml] = useState<string | null>(null);
useEffect(() => { useEffect(() => {
uri uri ? fetchText(uri).then(setXml).catch(onError) : setXml(null);
? fetchText(uri)
.then(setXml)
.catch(onError)
: setXml(null);
}, [onError, uri]); }, [onError, uri]);
return <SvgXml xml={xml} override={props} />; return <SvgXml xml={xml} override={props} />;
} }
+1628 -1577
View File
File diff suppressed because it is too large Load Diff