mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-06 07:06:11 +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]
|
||||
.*/node_modules/resolve/test/resolver/malformed_package_json/package.json
|
||||
|
||||
[include]
|
||||
|
||||
|
||||
9
jest.config.ts
Normal file
9
jest.config.ts
Normal 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;
|
||||
33
package.json
33
package.json
@@ -59,36 +59,39 @@
|
||||
"react-native": ">=0.50.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"css-select": "^4.2.1",
|
||||
"css-tree": "^1.0.0-alpha.39"
|
||||
"css-select": "^5.1.0",
|
||||
"css-tree": "^1.1.3"
|
||||
},
|
||||
"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/eslint-config": "0.0.7",
|
||||
"@react-native-community/eslint-plugin": "^1.0.0",
|
||||
"@react-native-community/eslint-config": "^3.0.2",
|
||||
"@react-native-community/eslint-plugin": "^1.2.0",
|
||||
"@types/css-tree": "^1.0.3",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "*",
|
||||
"@types/react": "^17.0.16",
|
||||
"@types/react-native": "^0.63.40",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-jest": "^25.1.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-flowtype": "^4.6.0",
|
||||
"eslint-plugin-prettier": "^3.1.2",
|
||||
"eslint-plugin-react": "^7.18.3",
|
||||
"babel-jest": "^28.1.0",
|
||||
"eslint": "^8.16.0",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.30.0",
|
||||
"flow-bin": "^0.119.1",
|
||||
"flow-typed": "^3.0.0",
|
||||
"flowgen": "^1.10.0",
|
||||
"jest": "^25.1.0",
|
||||
"jest": "^28.1.0",
|
||||
"pegjs": "^0.10.0",
|
||||
"prettier": "^1.19.1",
|
||||
"prettier": "^2.6.2",
|
||||
"react": "^16.13.0",
|
||||
"react-native": "^0.62.3",
|
||||
"react-test-renderer": "^16.13.0",
|
||||
"release-it": "^14.12.5",
|
||||
"typescript": "^3.8.3"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "react-native"
|
||||
"ts-node": "^10.8.0",
|
||||
"typescript": "^4.7.2"
|
||||
},
|
||||
"nativePackage": true
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ function remeasure() {
|
||||
|
||||
export class WebShape<
|
||||
P extends BaseProps = BaseProps,
|
||||
C = {}
|
||||
C = {},
|
||||
> extends React.Component<P, C> {
|
||||
[x: string]: unknown;
|
||||
_remeasureMetricsOnActivation: () => void;
|
||||
|
||||
23
src/css.tsx
23
src/css.tsx
@@ -117,7 +117,7 @@ function existsOne(
|
||||
elems: Array<XmlAST | string>,
|
||||
): boolean {
|
||||
return elems.some(
|
||||
elem =>
|
||||
(elem) =>
|
||||
typeof elem === 'object' &&
|
||||
(predicate(elem) || existsOne(predicate, elem.children)),
|
||||
);
|
||||
@@ -290,7 +290,7 @@ function filterByPseudos(selectors: FlatSelectorList) {
|
||||
csstree.generate({
|
||||
type: 'Selector',
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
const specs = selectors.map(selectorWithSpecificity);
|
||||
return exec(specs, len).map(s => s.selector);
|
||||
return exec(specs, len).map((s) => s.selector);
|
||||
}
|
||||
|
||||
const declarationParseProps = {
|
||||
@@ -517,14 +517,17 @@ function CSSStyleDeclaration(ast: XmlAST) {
|
||||
styles,
|
||||
declarationParseProps,
|
||||
) as DeclarationList;
|
||||
declarations.children.each(node => {
|
||||
declarations.children.each((node) => {
|
||||
try {
|
||||
const { property, value, important } = node as Declaration;
|
||||
const name = property.trim();
|
||||
priority.set(name, important);
|
||||
style[camelCase(name)] = csstree.generate(value).trim();
|
||||
} catch (styleError) {
|
||||
if (styleError.message !== 'Unknown node type: undefined') {
|
||||
if (
|
||||
styleError instanceof Error &&
|
||||
styleError.message !== 'Unknown node type: undefined'
|
||||
) {
|
||||
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: " +
|
||||
styleError,
|
||||
@@ -666,7 +669,7 @@ export const inlineStyles: Middleware = function inlineStyles(
|
||||
},
|
||||
});
|
||||
} catch (selectError) {
|
||||
if (selectError.constructor === SyntaxError) {
|
||||
if (selectError instanceof SyntaxError) {
|
||||
console.warn(
|
||||
'Warning: Syntax error when trying to select \n\n' +
|
||||
selectorStr +
|
||||
@@ -695,11 +698,7 @@ export function SvgCssUri(props: UriProps) {
|
||||
const { uri, onError = err } = props;
|
||||
const [xml, setXml] = useState<string | null>(null);
|
||||
useEffect(() => {
|
||||
uri
|
||||
? fetchText(uri)
|
||||
.then(setXml)
|
||||
.catch(onError)
|
||||
: setXml(null);
|
||||
uri ? fetchText(uri).then(setXml).catch(onError) : setXml(null);
|
||||
}, [onError, uri]);
|
||||
return <SvgCss xml={xml} override={props} />;
|
||||
}
|
||||
|
||||
@@ -252,8 +252,12 @@ export default class Shape<P> extends Component<P> {
|
||||
* representative example / reproduction.
|
||||
* */
|
||||
getBBox = (options?: SVGBoundingBoxOptions): SVGRect => {
|
||||
const { fill = true, stroke = true, markers = true, clipped = true } =
|
||||
options || {};
|
||||
const {
|
||||
fill = true,
|
||||
stroke = true,
|
||||
markers = true,
|
||||
clipped = true,
|
||||
} = options || {};
|
||||
const handle = findNodeHandle(this.root as Component);
|
||||
return RNSVGRenderableManager.getBBox(handle, {
|
||||
fill,
|
||||
|
||||
@@ -5,12 +5,7 @@
|
||||
const DEG_TO_RAD = Math.PI / 180;
|
||||
|
||||
export const identity: [number, number, number, number, number, number] = [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1, 0, 0, 1, 0, 0,
|
||||
];
|
||||
|
||||
let a = 1;
|
||||
|
||||
@@ -117,7 +117,7 @@ const SvgTouchableMixin = {
|
||||
};
|
||||
|
||||
const touchKeys = Object.keys(SvgTouchableMixin);
|
||||
const touchVals = touchKeys.map(key => SvgTouchableMixin[key]);
|
||||
const touchVals = touchKeys.map((key) => SvgTouchableMixin[key]);
|
||||
const numTouchKeys = touchKeys.length;
|
||||
|
||||
export default (target: { [x: string]: unknown; state: unknown }) => {
|
||||
|
||||
@@ -7,7 +7,6 @@ const contextFillBrush = [3];
|
||||
const contextStrokeBrush = [4];
|
||||
|
||||
export default function extractBrush(color?: ColorValue) {
|
||||
|
||||
if (!color || color === 'none') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export default function extractGradient(
|
||||
|
||||
const stops = [];
|
||||
const childArray = children
|
||||
? Children.map(children, child =>
|
||||
? Children.map(children, (child) =>
|
||||
React.cloneElement(child, {
|
||||
parent,
|
||||
}),
|
||||
|
||||
@@ -11,10 +11,7 @@ export default function extractLengthList(
|
||||
} else if (typeof lengthList === 'number') {
|
||||
return [lengthList];
|
||||
} else if (typeof lengthList === 'string') {
|
||||
return lengthList
|
||||
.trim()
|
||||
.replace(commaReg, ' ')
|
||||
.split(spaceReg);
|
||||
return lengthList.trim().replace(commaReg, ' ').split(spaceReg);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ import extractLengthList from './extractLengthList';
|
||||
import { pickNotNil } from '../util';
|
||||
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 fontFamilySuffix = /[\s"']*$/;
|
||||
const commaReg = /\s*,\s*/g;
|
||||
|
||||
@@ -3,17 +3,8 @@ import { parse } from './transform';
|
||||
import { NumberProp, TransformedProps, TransformProps } from './types';
|
||||
|
||||
function appendTransformProps(props: TransformedProps) {
|
||||
const {
|
||||
x,
|
||||
y,
|
||||
originX,
|
||||
originY,
|
||||
scaleX,
|
||||
scaleY,
|
||||
rotation,
|
||||
skewX,
|
||||
skewY,
|
||||
} = props;
|
||||
const { x, y, originX, originY, scaleX, scaleY, rotation, skewX, skewY } =
|
||||
props;
|
||||
appendTransform(
|
||||
x + originX,
|
||||
y + originY,
|
||||
|
||||
@@ -36,9 +36,8 @@ export default function extractViewBox(props: {
|
||||
return null;
|
||||
}
|
||||
|
||||
const params = (Array.isArray(viewBox)
|
||||
? viewBox
|
||||
: viewBox.trim().split(spacesRegExp)
|
||||
const params = (
|
||||
Array.isArray(viewBox) ? viewBox : viewBox.trim().split(spacesRegExp)
|
||||
).map(Number);
|
||||
|
||||
if (params.length !== 4 || params.some(isNaN)) {
|
||||
|
||||
13
src/xml.tsx
13
src/xml.tsx
@@ -110,9 +110,10 @@ export const err = console.error.bind(console);
|
||||
|
||||
export function SvgXml(props: XmlProps) {
|
||||
const { onError = err, xml, override } = props;
|
||||
const ast = useMemo<JsxAST | null>(() => (xml !== null ? parse(xml) : null), [
|
||||
xml,
|
||||
]);
|
||||
const ast = useMemo<JsxAST | null>(
|
||||
() => (xml !== null ? parse(xml) : null),
|
||||
[xml],
|
||||
);
|
||||
|
||||
try {
|
||||
return <SvgAst ast={ast} override={override || props} />;
|
||||
@@ -134,11 +135,7 @@ export function SvgUri(props: UriProps) {
|
||||
const { onError = err, uri } = props;
|
||||
const [xml, setXml] = useState<string | null>(null);
|
||||
useEffect(() => {
|
||||
uri
|
||||
? fetchText(uri)
|
||||
.then(setXml)
|
||||
.catch(onError)
|
||||
: setXml(null);
|
||||
uri ? fetchText(uri).then(setXml).catch(onError) : setXml(null);
|
||||
}, [onError, uri]);
|
||||
return <SvgXml xml={xml} override={props} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user