Skip to content

Commit

Permalink
Encode ..'s in asset paths to fix facebook#290
Browse files Browse the repository at this point in the history
  • Loading branch information
Ian Ownbey committed Mar 16, 2020
1 parent 0480dad commit 6d27fb8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
16 changes: 6 additions & 10 deletions packages/metro/src/Assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,9 @@ async function getAssetData(
platform: ?string = null,
publicPath: string,
): Promise<AssetData> {
// If the path of the asset is outside of the projectRoot, we don't want to
// use `path.join` since this will generate an incorrect URL path. In that
// case we just concatenate the publicPath with the relative path.
let assetUrlPath = localPath.startsWith('..')
? publicPath.replace(/\/$/, '') + '/' + path.dirname(localPath)
: path.join(publicPath, path.dirname(localPath));
// OKHTTP (Android HTTP client) strips out any '..' from a URL so we replace them with 2 _'s.
const escapedLocalPath = localPath.replace(/\.\.\//, '__/');
let assetUrlPath = path.join(publicPath, path.dirname(escapedLocalPath));

// On Windows, change backslashes to slashes to get proper URL path from file path.
if (path.sep === '\\') {
Expand Down Expand Up @@ -276,8 +273,8 @@ async function getAsset(
relativePath,
new Set(platform != null ? [platform] : []),
);

const absolutePath = path.resolve(projectRoot, relativePath);
// Replaces __/ or __\ with ../ or ..\
const absolutePath = path.resolve(projectRoot, relativePath.replace(/__(\/|\\)/, '..$1'));

if (!assetExts.includes(assetData.type)) {
throw new Error(
Expand All @@ -290,8 +287,7 @@ async function getAsset(
`'${relativePath}' could not be found, because it cannot be found in the project root or any watch folder`,
);
}

const record = await getAbsoluteAssetRecord(absolutePath, platform);
const record = await getAbsoluteAssetRecord(absolutePath, platform); // Matches __/ or __\

for (let i = 0; i < record.scales.length; i++) {
if (record.scales[i] >= assetData.resolution) {
Expand Down
16 changes: 13 additions & 3 deletions packages/metro/src/__tests__/Assets-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ describe('getAsset', () => {
).toEqual(['b4 image', 'b4 ios image']);
});

it('should find an image located on a watchFolder', async () => {
it('should find an image located on a watchFolder with encoded path', async () => {
mkdirp.sync('/anotherfolder');

writeImages({
Expand All @@ -129,7 +129,7 @@ describe('getAsset', () => {

expect(
await getAssetStr(
'../anotherfolder/b.png',
'__/anotherfolder/b.png',
'/root',
['/anotherfolder'],
null,
Expand All @@ -146,7 +146,7 @@ describe('getAsset', () => {
});

await expect(
getAssetStr('../anotherfolder/b.png', '/root', [], null, ['png']),
getAssetStr('__/anotherfolder/b.png', '/root', [], null, ['png']),
).rejects.toBeInstanceOf(Error);
});
});
Expand Down Expand Up @@ -191,6 +191,16 @@ describe('getAssetData', () => {
});
});

it('should escape out .. in assetData', () => {
fs.writeFileSync(path.join('/', '[email protected]'), 'b1 image');

return getAssetData('/b.png', '../b.png', [], null, '/assets').then(
data => {
expect(data.httpServerLocation).toEqual('/assets/__');
},
);
});

it('should get assetData for non-png images', async () => {
writeImages({
'[email protected]': 'b1 image',
Expand Down

0 comments on commit 6d27fb8

Please sign in to comment.