Skip to content

Commit

Permalink
Fix resolving assets outside of the project root (#27932)
Browse files Browse the repository at this point in the history
Summary:
When an asset is outside of the metro project root, it can lead to relative paths like `/assets/../../node_modules/coolpackage/image.png` as the `httpServerLocation`. This can happen for example when using yarn workspaces with hoisted node_modules.

This causes issues when bundling on iOS since we use this path in the filesystem. To avoid this we replace `../` with `_` to preserve the uniqueness of the path while avoiding these kind of problematic relative paths. The same logic is used when bundling assets in the rn-cli.

CLI part of this PR: react-native-community/cli#939

## Changelog

[General] [Fixed] - Fix resolving assets outside of the project root
Pull Request resolved: #27932

Test Plan: Tested that an asset in a hoisted node_modules package doesn't show up before this patch and does after in a release build.

Differential Revision: D19690587

Pulled By: cpojer

fbshipit-source-id: 8a9c68af04594ce1503a810ecf2e97ef5bfb8004
  • Loading branch information
janicduplessis authored and facebook-github-bot committed Feb 3, 2020
1 parent f295d7f commit 7deeec7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
7 changes: 6 additions & 1 deletion Libraries/Image/AssetSourceResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,12 @@ class AssetSourceResolver {
*/
scaledAssetURLNearBundle(): ResolvedAssetSource {
const path = this.jsbundleUrl || 'file://';
return this.fromSource(path + getScaledAssetPath(this.asset));
return this.fromSource(
// Assets can have relative paths outside of the project root.
// When bundling them we replace `../` with `_` to make sure they
// don't end up outside of the expected assets directory.
path + getScaledAssetPath(this.asset).replace(/\.\.\//g, '_'),
);
}

/**
Expand Down
46 changes: 46 additions & 0 deletions Libraries/Image/__tests__/resolveAssetSource-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,29 @@ describe('resolveAssetSource', () => {
},
);
});

it('resolves an image with a relative path outside of root', () => {
expectResolvesAsset(
{
__packager_asset: true,
fileSystemLocation: '/module/a',
httpServerLocation: '/assets/../../module/a',
width: 100,
height: 200,
scales: [1],
hash: '5b6f00f',
name: 'logo',
type: 'png',
},
{
__packager_asset: true,
width: 100,
height: 200,
uri: 'file:///Path/To/Sample.app/assets/__module/a/logo.png',
scale: 1,
},
);
});
});

describe('bundle was loaded from assets on Android', () => {
Expand Down Expand Up @@ -175,6 +198,29 @@ describe('resolveAssetSource', () => {
},
);
});

it('resolves an image with a relative path outside of root', () => {
expectResolvesAsset(
{
__packager_asset: true,
fileSystemLocation: '/module/a',
httpServerLocation: '/assets/../../module/a',
width: 100,
height: 200,
scales: [1],
hash: '5b6f00f',
name: 'logo',
type: 'png',
},
{
__packager_asset: true,
width: 100,
height: 200,
uri: '__module_a_logo',
scale: 1,
},
);
});
});

describe('bundle was loaded from file on Android', () => {
Expand Down

0 comments on commit 7deeec7

Please sign in to comment.