Skip to content

Commit 7deeec7

Browse files
janicduplessisfacebook-github-bot
authored andcommitted
Fix resolving assets outside of the project root (#27932)
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
1 parent f295d7f commit 7deeec7

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

Libraries/Image/AssetSourceResolver.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,12 @@ class AssetSourceResolver {
114114
*/
115115
scaledAssetURLNearBundle(): ResolvedAssetSource {
116116
const path = this.jsbundleUrl || 'file://';
117-
return this.fromSource(path + getScaledAssetPath(this.asset));
117+
return this.fromSource(
118+
// Assets can have relative paths outside of the project root.
119+
// When bundling them we replace `../` with `_` to make sure they
120+
// don't end up outside of the expected assets directory.
121+
path + getScaledAssetPath(this.asset).replace(/\.\.\//g, '_'),
122+
);
118123
}
119124

120125
/**

Libraries/Image/__tests__/resolveAssetSource-test.js

+46
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,29 @@ describe('resolveAssetSource', () => {
143143
},
144144
);
145145
});
146+
147+
it('resolves an image with a relative path outside of root', () => {
148+
expectResolvesAsset(
149+
{
150+
__packager_asset: true,
151+
fileSystemLocation: '/module/a',
152+
httpServerLocation: '/assets/../../module/a',
153+
width: 100,
154+
height: 200,
155+
scales: [1],
156+
hash: '5b6f00f',
157+
name: 'logo',
158+
type: 'png',
159+
},
160+
{
161+
__packager_asset: true,
162+
width: 100,
163+
height: 200,
164+
uri: 'file:///Path/To/Sample.app/assets/__module/a/logo.png',
165+
scale: 1,
166+
},
167+
);
168+
});
146169
});
147170

148171
describe('bundle was loaded from assets on Android', () => {
@@ -175,6 +198,29 @@ describe('resolveAssetSource', () => {
175198
},
176199
);
177200
});
201+
202+
it('resolves an image with a relative path outside of root', () => {
203+
expectResolvesAsset(
204+
{
205+
__packager_asset: true,
206+
fileSystemLocation: '/module/a',
207+
httpServerLocation: '/assets/../../module/a',
208+
width: 100,
209+
height: 200,
210+
scales: [1],
211+
hash: '5b6f00f',
212+
name: 'logo',
213+
type: 'png',
214+
},
215+
{
216+
__packager_asset: true,
217+
width: 100,
218+
height: 200,
219+
uri: '__module_a_logo',
220+
scale: 1,
221+
},
222+
);
223+
});
178224
});
179225

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

0 commit comments

Comments
 (0)