Skip to content

Commit

Permalink
fix(SvgCssUri): support rendering fallback instead of crashing the ap…
Browse files Browse the repository at this point in the history
…p when loading invalid content from remote svg file (software-mansion#2196)

This crash issue still happening for SvgCssUri component
software-mansion#1760

Apply similar fix software-mansion#2071
specifically for SvgCSSUri component to prevent crashes due to invalid svg content

What issues does the pull request solve? Please tag them so that they will get automatically closed once the PR is merged
-> When loading invalid svg uri with SvgCSSUri, the app crashes crashes. For example the content returning html content instead of valid svg content.

How did you implement the solution?
-> Passing the fallback prop to SvgCss where will be render when error being captured

What areas of the library does it impact?
SvgCss and SvgUriCss
  • Loading branch information
quangkcao authored Jan 3, 2024
1 parent 07b9ca5 commit ff18553
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 7 deletions.
1 change: 1 addition & 0 deletions TestsExample/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Test2080 from './src/Test2080';
import PointerEventsBoxNone from './src/PointerEventsBoxNone';
import Test2071 from './src/Test2071';
import Test2089 from './src/Test2089';
import Test2196 from './src/Test2196';

export default function App() {
return <ColorTest />;
Expand Down
59 changes: 59 additions & 0 deletions TestsExample/src/Test2196.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as React from 'react';
import {View, Button, Text} from 'react-native';
import Svg, {Circle} from 'react-native-svg';
import {SvgCssUri} from 'react-native-svg/css';

const URIs = {
invalid: 'https://en.wikipedia.org/wiki/File:Vector-based_example.svg',
valid:
'https://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg',
};

export default function App() {
const [uri, setUri] = React.useState(URIs.invalid);

const handlePress = React.useCallback(() => {
const newUri = uri === URIs.valid ? URIs.invalid : URIs.valid;
setUri(newUri);
}, [uri]);

const title =
uri === URIs.invalid
? 'Render fallback due to invalid SVG'
: 'Render Valid SVG';

const buttonTitle = `Switch to ${
uri === URIs.invalid ? 'valid' : 'invalid'
} SVG`;

return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>{title}</Text>
<View style={{paddingVertical: 20}}>
<SvgCssUri
onError={() => {}}
uri={uri}
width={100}
height={100}
fallback={
<Svg
width={100}
height={100}
viewBox="0 0 100 100"
transform={[{scaleX: 1}, {scaleY: -1}]}>
<Circle
cx={50}
cy={50}
r={40}
stroke="black"
strokeWidth={3}
fill="red"
/>
</Svg>
}
/>
</View>
<Button onPress={handlePress} title={buttonTitle} />
</View>
);
}
19 changes: 12 additions & 7 deletions src/css/css.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -688,12 +688,17 @@ export const inlineStyles: Middleware = function inlineStyles(
};

export function SvgCss(props: XmlProps) {
const { xml, override } = props;
const ast = useMemo<JsxAST | null>(
() => (xml !== null ? parse(xml, inlineStyles) : null),
[xml]
);
return <SvgAst ast={ast} override={override || props} />;
const {xml, override, fallback, onError = err} = props;
try {
const ast = useMemo<JsxAST | null>(
() => (xml !== null ? parse(xml, inlineStyles) : null),
[xml]
);
return <SvgAst ast={ast} override={override || props} />;
} catch (error) {
onError(error);
return fallback ?? null;
}
}

export function SvgCssUri(props: UriProps) {
Expand All @@ -716,7 +721,7 @@ export function SvgCssUri(props: UriProps) {
if (isError) {
return fallback ?? null;
}
return <SvgCss xml={xml} override={props} />;
return <SvgCss xml={xml} override={props} fallback={fallback}/>;
}

// Extending Component is required for Animated support.
Expand Down

0 comments on commit ff18553

Please sign in to comment.