react-native-svg icon indicating copy to clipboard operation
react-native-svg copied to clipboard

replace error on xml source after upgrading to React Native 0.75

Open IncrediblePony opened this issue 1 year ago • 13 comments
trafficstars

Description

I have this xml representing an svg:

<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#000000" version="1.1" id="Capa_1" width="800px" height="800px" viewBox="0 0 495.398 495.398" xml:space="preserve"><g><g><g><path d="M487.083,225.514l-75.08-75.08V63.704c0-15.682-12.708-28.391-28.413-28.391c-15.669,0-28.377,12.709-28.377,28.391     v29.941L299.31,37.74c-27.639-27.624-75.694-27.575-103.27,0.05L8.312,225.514c-11.082,11.104-11.082,29.071,0,40.158     c11.087,11.101,29.089,11.101,40.172,0l187.71-187.729c6.115-6.083,16.893-6.083,22.976-0.018l187.742,187.747     c5.567,5.551,12.825,8.312,20.081,8.312c7.271,0,14.541-2.764,20.091-8.312C498.17,254.586,498.17,236.619,487.083,225.514z"/><path d="M257.561,131.836c-5.454-5.451-14.285-5.451-19.723,0L72.712,296.913c-2.607,2.606-4.085,6.164-4.085,9.877v120.401     c0,28.253,22.908,51.16,51.16,51.16h81.754v-126.61h92.299v126.61h81.755c28.251,0,51.159-22.907,51.159-51.159V306.79     c0-3.713-1.465-7.271-4.085-9.877L257.561,131.836z"/></g></g></g></svg>

This is the unformatted xml sent from my provider, which my react-native application receives:

"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" fill=\"#000000\" version=\"1.1\" id=\"Capa_1\" width=\"800px\" height=\"800px\" viewBox=\"0 0 495.398 495.398\" xml:space=\"preserve\">
<g>
        <g>
                <g>
                        <path d=\"M487.083,225.514l-75.08-75.08V63.704c0-15.682-12.708-28.391-28.413-28.391c-15.669,0-28.377,12.709-28.377,28.391     v29.941L299.31,37.74c-27.639-27.624-75.694-27.575-103.27,0.05L8.312,225.514c-11.082,11.104-11.082,29.071,0,40.158     c11.087,11.101,29.089,11.101,40.172,0l187.71-187.729c6.115-6.083,16.893-6.083,22.976-0.018l187.742,187.747     c5.567,5.551,12.825,8.312,20.081,8.312c7.271,0,14.541-2.764,20.091-8.312C498.17,254.586,498.17,236.619,487.083,225.514z\"/>
                        <path d=\"M257.561,131.836c-5.454-5.451-14.285-5.451-19.723,0L72.712,296.913c-2.607,2.606-4.085,6.164-4.085,9.877v120.401     c0,28.253,22.908,51.16,51.16,51.16h81.754v-126.61h92.299v126.61h81.755c28.251,0,51.159-22.907,51.159-51.159V306.79     c0-3.713-1.465-7.271-4.085-9.877L257.561,131.836z\"/>
                </g>
        </g>
</g>
</svg>"

The minified svg icon renders as intended in online svg tools. The "raw" svg icon doesn't. When attempting to load the icon from the xml I get this errormessage:

ERROR: TypeError: An error was thrown when attempting to render log messages via LogBox.

args[0].replace is not a function (it is undefined), js engine: hermes 
    at SvgXml (http://10.0.2.2:8081/index.bundle//&platform=android&dev=true&lazy=true&minify=false&app=com.glfr&modulesOnly=false&runModule=true:430621:31)

The error is thrown here: node_modules/react-native-svg/src/xml.tsx in function SvgXml on line 77.

export function SvgXml(props: XmlProps) {
  const { onError = err, xml, override, fallback } = props;

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

Why would this issue occur?

Steps to reproduce

  1. Make an xml file with the raw xml/svg presented in the description
  2. Attempt to render it with <SvgXml />
import { SvgFromXml, SvgXml } from 'react-native-svg'

export const QuickLinkItemView = ({ name, unhandledUrl, icon, clubId }: QuickLinkProps) => {

  return (
    <View>
      <SvgXml xml={/* iconxml */} width={30} height={30} fill={'black'} />
    </View>
  )
}

Snack or a link to a repository

Snack

SVG version

15.7.1

React Native version

0.75.3

Platforms

Android

JavaScript runtime

Hermes

Workflow

React Native

Architecture

Fabric (New Architecture)

Build type

Debug app & dev bundle

Device

Android emulator

Device model

No response

Acknowledgements

Yes

IncrediblePony avatar Sep 18 '24 11:09 IncrediblePony

https://snack.expo.dev/Rl2Jqv8kyotpma0onZCAO

IncrediblePony avatar Sep 18 '24 12:09 IncrediblePony

Hi @IncrediblePony, Your SVG has escaped double quotes, \" which makes it invalid. You can validate the SVG string and check if it should render properly using this tool: https://validator.w3.org/#validate_by_input. react-native-svg has nothing to do here, as it's clearly not a valid xml. As a workaround, you should probably fetch the svg by yourself and just .replaceAll(`\"`, `"`) to fix the quotes before passing it to the SvgXml.

jakex7 avatar Sep 18 '24 14:09 jakex7

image

The funny thing is that this calendar icon:

<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" id=\"Capa_1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 489.2 489.2\" style=\"enable-background:new 0 0 489.2 489.2;\" xml:space=\"preserve\"><g><g><path d=\"M177.8,238.1c0,4.5-3.6,8.1-8.1,8.1h-30.4c-4.5,0-8.1-3.6-8.1-8.1v-30.4c0-4.5,3.6-8.1,8.1-8.1h30.4    c4.5,0,8.1,3.6,8.1,8.1V238.1z M241.3,207.8c0-4.5-3.6-8.1-8.1-8.1h-30.4c-4.5,0-8.1,3.6-8.1,8.1v30.4c0,4.5,3.6,8.1,8.1,8.1h30.4    c4.5,0,8.1-3.6,8.1-8.1V207.8z M304.8,207.8c0-4.5-3.6-8.1-8.1-8.1h-30.4c-4.5,0-8.1,3.6-8.1,8.1v30.4c0,4.5,3.6,8.1,8.1,8.1h30.4    c4.5,0,8.1-3.6,8.1-8.1V207.8z M177.8,269.6c0-4.5-3.6-8.1-8.1-8.1h-30.4c-4.5,0-8.1,3.6-8.1,8.1V300c0,4.5,3.6,8.1,8.1,8.1h30.4    c4.5,0,8.1-3.6,8.1-8.1V269.6z M241.3,269.6c0-4.5-3.6-8.1-8.1-8.1h-30.4c-4.5,0-8.1,3.6-8.1,8.1V300c0,4.5,3.6,8.1,8.1,8.1h30.4    c4.5,0,8.1-3.6,8.1-8.1V269.6z M296.7,261.5h-30.4c-4.5,0-8.1,3.6-8.1,8.1V300c0,4.5,3.6,8.1,8.1,8.1h30.4c4.5,0,8.1-3.6,8.1-8.1    v-30.4C304.8,265.1,301.2,261.5,296.7,261.5z M106.1,323.3H75.8c-4.5,0-8.1,3.6-8.1,8.1v30.4c0,4.5,3.6,8.1,8.1,8.1h30.4    c4.5,0,8.1-3.6,8.1-8.1v-30.4C114.3,326.9,110.6,323.3,106.1,323.3z M114.3,269.6c0-4.5-3.6-8.1-8.1-8.1H75.8    c-4.5,0-8.1,3.6-8.1,8.1V300c0,4.5,3.6,8.1,8.1,8.1h30.4c4.5,0,8.1-3.6,8.1-8.1V269.6z M233.2,323.3h-30.4c-4.5,0-8.1,3.6-8.1,8.1    v30.4c0,4.5,3.6,8.1,8.1,8.1h30.4c4.5,0,8.1-3.6,8.1-8.1v-30.4C241.3,326.9,237.7,323.3,233.2,323.3z M169.7,323.3h-30.4    c-4.5,0-8.1,3.6-8.1,8.1v30.4c0,4.5,3.6,8.1,8.1,8.1h30.4c4.5,0,8.1-3.6,8.1-8.1v-30.4C177.8,326.9,174.2,323.3,169.7,323.3z     M360.2,246.3c4.5,0,8.1-3.6,8.1-8.1v-30.4c0-4.5-3.6-8.1-8.1-8.1h-30.4c-4.5,0-8.1,3.6-8.1,8.1v30.4c0,4.5,3.6,8.1,8.1,8.1H360.2    z M47.7,435.9h230.7c-3.7-11.6-5.8-24-5.9-36.8H47.7c-6,0-10.8-4.9-10.8-10.8V171h361.7v101.1c12.8,0.1,25.2,2,36.8,5.7V94.9    c0-26.3-21.4-47.7-47.7-47.7h-53.4V17.8c0-9.6-7.8-17.4-17.4-17.4h-27.1c-9.6,0-17.4,7.8-17.4,17.4v29.5H163V17.8    c0-9.6-7.8-17.4-17.4-17.4h-27.1c-9.6,0-17.4,7.8-17.4,17.4v29.5H47.7C21.4,47.3,0,68.7,0,95v293.3C0,414.5,21.4,435.9,47.7,435.9    z M489.2,397.7c0,50.3-40.8,91.1-91.1,91.1S307,448,307,397.7s40.8-91.1,91.1-91.1S489.2,347.4,489.2,397.7z M444.1,374.1    c0-2.9-1.1-5.7-3.2-7.7c-4.3-4.3-11.2-4.3-15.5,0L385.8,406l-15.2-15.2c-4.3-4.3-11.2-4.3-15.5,0c-2.1,2.1-3.2,4.8-3.2,7.7    c0,2.9,1.1,5.7,3.2,7.7l22.9,22.9c4.3,4.3,11.2,4.3,15.5,0l47.3-47.3C443,379.8,444.1,377,444.1,374.1z\"/></g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg>

This icon renders perfectly fine (as shown on screendump). Same goes for the knife and spoon icon:

<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"48px\" viewBox=\"0 0 24 24\" width=\"48px\" fill=\"#000000\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M8.1 13.34l2.83-2.83L3.91 3.5c-1.56 1.56-1.56 4.09 0 5.66l4.19 4.18zm6.78-1.81c1.53.71 3.68.21 5.27-1.38 1.91-1.91 2.28-4.65.81-6.12-1.46-1.46-4.2-1.1-6.12.81-1.59 1.59-2.09 3.74-1.38 5.27L3.7 19.87l1.41 1.41L12 14.41l6.88 6.88 1.41-1.41L13.41 13l1.47-1.47z\"/></svg>

The only problem is with the "Home" icon as described in the issue. All of them comes from the same source (our own icon library in from our database). So I don't really see that this should be the issue.

Either way, why would the code fail outright? Why not just a warning instead of a full on error, which breaks running code?

IncrediblePony avatar Sep 19 '24 07:09 IncrediblePony

@IncrediblePony can you try to run that with onError props and check what will be inside? <SvgXml xml={/* iconxml */} onError={(err) => console.log(err)} width={30} height={30} fill={'black'} />

bohdanprog avatar Sep 19 '24 07:09 bohdanprog

function removeBackslashes(input: string): string {
  return input.replaceAll('\\"', '"')
}

<SvgXml
    xml={removeBackslashes(icon)}
    onError={err => console.log('Xml icon error -- ', err)}
    width={30}
    height={30}
    fill={'black'}
/>
 LOG  Xml icon error --  [TypeError: Cannot read property 'push' of null]
 LOG  Xml icon error --  [TypeError: Cannot convert null value to object]

This is the result.

The strange thing is that these issues were never a problem before I started to upgrade from 0.72 RN to 0.75

IncrediblePony avatar Sep 19 '24 07:09 IncrediblePony

@IncrediblePony I tried to reproduce that issue with those dependencies:

   "react": "18.3.1",
    "react-native": "0.75.1",

Would you be able to create a simple repo with that issue?

bohdanprog avatar Sep 19 '24 07:09 bohdanprog

We might have been going down a wrong avenue here - the character escaped double qoutes are just a result of displaying a string in my terminal. I apologize. The component handles the escape characters just fine it would seem.

We ran the broken svg through the "optimizer" here: https://www.svgviewer.dev/

Broken svg:

<?xml version="1.0" encoding="iso-8859-1"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo
Mixer Tools -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#000000"
  version="1.1" id="Capa_1" width="800px" height="800px" viewBox="0 0 495.398 495.398"
  xml:space="preserve">
  <g>
    <g>
      <g>
        <path d= "M487.083,225.514l-75.08-75.08V63.704c0-15.682-12.708-28.391-28.413-28.391c-15.669,0-28.377,12.709-28.377,28.391     v29.941L299.31,37.74c-27.639-27.624-75.694-27.575-103.27,0.05L8.312,225.514c-11.082,11.104-11.082,29.071,0,40.158     c11.087,11.101,29.089,11.101,40.172,0l187.71-187.729c6.115-6.083,16.893-6.083,22.976-0.018l187.742,187.747     c5.567,5.551,12.825,8.312,20.081,8.312c7.271,0,14.541-2.764,20.091-8.312C498.17,254.586,498.17,236.619,487.083,225.514z" />
        <path d= "M257.561,131.836c-5.454-5.451-14.285-5.451-19.723,0L72.712,296.913c-2.607,2.606-4.085,6.164-4.085,9.877v120.401     c0,28.253,22.908,51.16,51.16,51.16h81.754v-126.61h92.299v126.61h81.755c28.251,0,51.159-22.907,51.159-51.159V306.79     c0-3.713-1.465-7.271-4.085-9.877L257.561,131.836z" />
      </g>
    </g>
  </g>
</svg>

"optimized" svg:

<svg xmlns="http://www.w3.org/2000/svg" width="800" height="800" viewBox="0 0 495.398 495.398"
  xml:space="preserve">
  <path d="m487.083 225.514-75.08-75.08v-86.73c0-15.682-12.708-28.391-28.413-28.391-15.669 0-28.377 12.709-28.377 28.391v29.941L299.31 37.74c-27.639-27.624-75.694-27.575-103.27.05L8.312 225.514c-11.082 11.104-11.082 29.071 0 40.158 11.087 11.101 29.089 11.101 40.172 0l187.71-187.729c6.115-6.083 16.893-6.083 22.976-.018l187.742 187.747a28.34 28.34 0 0 0 20.081 8.312c7.271 0 14.541-2.764 20.091-8.312 11.086-11.086 11.086-29.053-.001-40.158"/>
  <path d="M257.561 131.836c-5.454-5.451-14.285-5.451-19.723 0L72.712 296.913a13.98 13.98 0 0 0-4.085 9.877v120.401c0 28.253 22.908 51.16 51.16 51.16h81.754v-126.61h92.299v126.61h81.755c28.251 0 51.159-22.907 51.159-51.159V306.79c0-3.713-1.465-7.271-4.085-9.877z"/>
</svg>

The optimized svg works flawlessly. I'm currently trying to figure out why.

IncrediblePony avatar Sep 19 '24 11:09 IncrediblePony

I'm getting:

cannot read property SvgXml of undefined

react: 18.3.1 react-native: 0.75.3 react-native-svg: 13.14.0

Is my error related to this issue?

amerllica avatar Sep 19 '24 15:09 amerllica

@amerllica give us any examples, please.

bohdanprog avatar Sep 19 '24 18:09 bohdanprog

@bohdanprog - alright. Your SVG Xml component is not able to handle and tags. Which is fair I'd say. The component doesn't seem to handle xml namespaces such as xmlns:xlink and xml:space as well. But it seems like it's mostly the doctype and xml tags which messes the svg's up.

IncrediblePony avatar Sep 26 '24 13:09 IncrediblePony

Dear @bohdanprog, by updating to 13.14.1 the issue got fixed.

amerllica avatar Sep 27 '24 09:09 amerllica

Dear @bohdanprog, by updating to 13.14.1 the issue got fixed.

Did you try to update to 15.7?

bohdanprog avatar Sep 27 '24 10:09 bohdanprog

No @bohdanprog, then my project needs to be updated and really it's so boring to me.

amerllica avatar Sep 27 '24 11:09 amerllica