Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageComponent - Characters truncated if image name contains '#' #37592

Open
flokol120 opened this issue May 26, 2023 · 5 comments
Open

ImageComponent - Characters truncated if image name contains '#' #37592

flokol120 opened this issue May 26, 2023 · 5 comments

Comments

@flokol120
Copy link

flokol120 commented May 26, 2023

Description

If a local image contains '#' in its name the file name will be truncated after the '#' e.g.: /data/user/0/com.imagetest/files/invalid#ThisSeemsToBeTreatedAsACommentOuch.jpg -> /data/user/0/com.imagetest/files/invalid. This will lead to React Native not finding the image on both android and iOS.

I did some digging using the android debugger but did not find the exact location where the '#' is truncated. However I suspect it may be some C++/C code as it happens on both platforms. Maybe the issue even has something to do with https://github.com/facebook/fresco which came into picture while debugging and not react native itself. But I hope some of the maintainers can help me locate the issue.

React Native Version

0.71.8

Output of npx react-native info

info Fetching system and libraries information...
System:
    OS: Windows 10 10.0.19045
    CPU: (16) x64 AMD Ryzen 7 5700G with Radeon Graphics
    Memory: 5.45 GB / 31.30 GB
  Binaries:
    Node: 18.16.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.19 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK:
      API Levels: 28, 29, 30, 31, 32, 33
      Build Tools: 30.0.2, 30.0.3, 31.0.0, 33.0.0, 33.0.1, 34.0.0, 34.0.0
      System Images: android-31 | Intel x86 Atom_64, android-31 | Google APIs Intel x86 Atom_64, android-33 | Google APIs Intel x86 Atom_64, android-33 | Google Play Intel x86 Atom_64
      Android NDK: Not Found
    Windows SDK: Not Found
  IDEs:
    Android Studio: Not Found
    Visual Studio: 17.4.33110.190 (Visual Studio Community 2022)
  Languages:
    Java: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.2.0 => 18.2.0
    react-native: 0.71.8 => 0.71.8
    react-native-windows: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

Easiest way to reproduce this when using android:

  1. Place a file containing '#' in the DocumentDirectoryPath of the app
  2. Load the image using uri in source of <Image ... />

When using iOS this is also an issue. To reproduce this you could download an image containing a '#' and display it using <Image />

Snack, code example, screenshot, or link to a repository

App.tsx:

import React, {useCallback, useMemo, useState} from 'react';
import {Button, Image, SafeAreaView, Text, useColorScheme} from 'react-native';

import {Colors} from 'react-native/Libraries/NewAppScreen';
import {DocumentDirectoryPath} from 'react-native-fs';

function App(): JSX.Element {
  const [isInvalid, setIsInvalid] = useState(true);

  const toggle = useCallback(
    () => setIsInvalid(oldVal => !oldVal),
    [setIsInvalid],
  );

  const isDarkMode = useColorScheme() === 'dark';

  const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
  };

  const currentImage = useMemo(
    () =>
      encodeURI(
        `file://${DocumentDirectoryPath}/${
          isInvalid ? 'invalid#ThisSeemsToBeTreatedAsACommentOuch' : 'valid&'
        }.jpg`,
      ),
    [isInvalid],
  );

  return (
    <SafeAreaView
      style={[backgroundStyle, {display: 'flex', flexDirection: 'column'}]}>
      <Text>Image:</Text>
      <Image
        source={{
          uri: currentImage,
        }}
        style={{width: 400, height: 400}}
        onError={error => console.log(error)}
      />
      <Button
        title={`The current image is ${isInvalid ? 'in' : ''}valid`}
        onPress={toggle}
      />
      <Text>path: {currentImage}</Text>
    </SafeAreaView>
  );
}

export default App;

The example uses react-native-fs for accessing the DocumentDirectoryPath more comfortably. But the path could be set manually too.

The two images invalid#ThisSeemsToBeTreatedAsACommentOuch.jpg as well as valid&.jpg must be placed in the apps DocumentDirectoryPath.

Copy link

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Nov 23, 2023
@flokol120
Copy link
Author

Still not addressed.

@github-actions github-actions bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Nov 24, 2023
Copy link

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label May 22, 2024
@flokol120
Copy link
Author

Yes, this issue still persists.

@github-actions github-actions bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label May 22, 2024
@mateoguzmana
Copy link
Contributor

I'm taking a look at this and I was able to reproduce it.

By debugging in Android, the URIs are not getting truncated either in the JS, C++ or Android side, they are going as-is to the request. See my screenshot below:

Request example

image

This doesn't seem to be a problem with React Native/Fresco itself but with how the request URIs are interpreted, I found this answer which has some good links with references explaining the reasons behind it.

It's good to mention that I tried to solve it by encoding part of the URI in the JS side, by doing uri.replace("#", "%23") (encoded symbol equivalent) but this also doesn't work.

I'm curious, what is your use case? maybe another solution would be to store the images with a different delimiter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants