mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-09 01:25:01 +00:00
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:
@@ -1,4 +1,5 @@
|
|||||||
[ignore]
|
[ignore]
|
||||||
|
.*/node_modules/resolve/test/resolver/malformed_package_json/package.json
|
||||||
|
|
||||||
[include]
|
[include]
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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 }) => {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -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 [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
@@ -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} />;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user