Skip to content

Commit cfbdbda

Browse files
committed
path fix
1 parent eaec3cf commit cfbdbda

File tree

8 files changed

+19
-12
lines changed

8 files changed

+19
-12
lines changed

packages/contentstack-export/src/commands/cm/stacks/export.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ContentstackClient,
1010
FlagInput,
1111
pathValidator,
12+
sanitizePath,
1213
} from '@contentstack/cli-utilities';
1314
import { ModuleExporter } from '../../../export';
1415
import { setupExportConfig, log, formatError, writeExportMetaFile } from '../../../utils';
@@ -108,7 +109,7 @@ export default class ExportCommand extends Command {
108109
exportConfig.region = this.region;
109110
exportConfig.developerHubBaseUrl = this.developerHubUrl;
110111
if (this.personalizeUrl) exportConfig.modules.personalize.baseURL[exportConfig.region.name] = this.personalizeUrl;
111-
exportDir = exportConfig.cliLogsPath || exportConfig.data || exportConfig.exportDir;
112+
exportDir = sanitizePath(exportConfig.cliLogsPath || exportConfig.data || exportConfig.exportDir);
112113
const managementAPIClient: ContentstackClient = await managementSDKClient(exportConfig);
113114
const moduleExporter = new ModuleExporter(managementAPIClient, exportConfig);
114115
await moduleExporter.start();

packages/contentstack-export/src/utils/export-config-handler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import merge from 'merge';
22
import * as path from 'path';
3-
import { configHandler, isAuthenticated, FlagInput, cliux } from '@contentstack/cli-utilities';
3+
import { configHandler, isAuthenticated, FlagInput, cliux, sanitizePath } from '@contentstack/cli-utilities';
44
import defaultConfig from '../config';
55
import { readFile } from './file-helper';
66
import { askExportDir, askAPIKey } from './interactive';
@@ -15,14 +15,14 @@ const setupConfig = async (exportCmdFlags: any): Promise<ExportConfig> => {
1515
const externalConfig = await readFile(exportCmdFlags['config']);
1616
config = merge.recursive(config, externalConfig);
1717
}
18-
config.exportDir = exportCmdFlags['data'] || exportCmdFlags['data-dir'] || config.data || (await askExportDir());
18+
config.exportDir = sanitizePath(exportCmdFlags['data'] || exportCmdFlags['data-dir'] || config.data || (await askExportDir()));
1919

2020
const pattern = /[*$%#<>{}!&?]/g;
2121
if (pattern.test(config.exportDir)) {
2222
cliux.print(`\nPlease add a directory path without any of the special characters: (*,&,{,},[,],$,%,<,>,?,!)`, {
2323
color: 'yellow',
2424
});
25-
config.exportDir = await askExportDir();
25+
config.exportDir = sanitizePath(await askExportDir());
2626
}
2727
config.exportDir = config.exportDir.replace(/['"]/g, '');
2828
config.exportDir = path.resolve(config.exportDir);

packages/contentstack-export/src/utils/logger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ function init(_logPath: string) {
137137
}
138138

139139
export const log = async (config: ExportConfig, message: any, type: string) => {
140-
const logsPath = config.cliLogsPath || config.data;
140+
const logsPath = sanitizePath(config.cliLogsPath || config.data);
141141
// ignoring the type argument, as we are not using it to create a logfile anymore
142142
if (type !== 'error') {
143143
// removed type argument from init method

packages/contentstack-import-setup/src/utils/import-config-handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ const setupConfig = async (importCmdFlags: any): Promise<ImportConfig> => {
2020
// config = merge.recursive(config, externalConfig);
2121
// }
2222

23-
config.contentDir = importCmdFlags['data'] || importCmdFlags['data-dir'] || config.data || (await askContentDir());
23+
config.contentDir = sanitizePath(importCmdFlags['data'] || importCmdFlags['data-dir'] || config.data || (await askContentDir()));
2424
const pattern = /[*$%#<>{}!&?]/g;
2525
if (pattern.test(config.contentDir)) {
2626
cliux.print(`\nPlease add a directory path without any of the special characters: (*,&,{,},[,],$,%,<,>,?,!)`, {
2727
color: 'yellow',
2828
});
29-
config.contentDir = await askContentDir();
29+
config.contentDir = sanitizePath(await askContentDir());
3030
}
3131
config.contentDir = config.contentDir.replace(/['"]/g, '');
3232
config.contentDir = path.resolve(config.contentDir);

packages/contentstack-import-setup/src/utils/logger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ function init(_logPath: string) {
140140
}
141141

142142
export const log = async (config: ImportConfig, message: any, type: string) => {
143-
config.cliLogsPath = config.cliLogsPath || config.data || path.join(__dirname, 'logs');
143+
config.cliLogsPath = sanitizePath(config.cliLogsPath || config.data || path.join(__dirname, 'logs'));
144144
// ignoring the type argument, as we are not using it to create a logfile anymore
145145
if (type !== 'error') {
146146
// removed type argument from init method

packages/contentstack-import/src/utils/import-config-handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ const setupConfig = async (importCmdFlags: any): Promise<ImportConfig> => {
2020
config = merge.recursive(config, externalConfig);
2121
}
2222

23-
config.contentDir = importCmdFlags['data'] || importCmdFlags['data-dir'] || config.data || (await askContentDir());
23+
config.contentDir = sanitizePath(importCmdFlags['data'] || importCmdFlags['data-dir'] || config.data || (await askContentDir()));
2424
const pattern = /[*$%#<>{}!&?]/g;
2525
if (pattern.test(config.contentDir)) {
2626
cliux.print(`\nPlease add a directory path without any of the special characters: (*,&,{,},[,],$,%,<,>,?,!)`, {
2727
color: 'yellow',
2828
});
29-
config.contentDir = await askContentDir();
29+
config.contentDir = sanitizePath(await askContentDir());
3030
}
3131
config.contentDir = config.contentDir.replace(/['"]/g, '');
3232
config.contentDir = path.resolve(config.contentDir);

packages/contentstack-import/src/utils/logger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ function init(_logPath: string) {
140140
}
141141

142142
export const log = async (config: ImportConfig, message: any, type: string) => {
143-
config.cliLogsPath = config.cliLogsPath || config.data || path.join(__dirname, 'logs');
143+
config.cliLogsPath = sanitizePath(config.cliLogsPath || config.data || path.join(__dirname, 'logs'));
144144
// ignoring the type argument, as we are not using it to create a logfile anymore
145145
if (type !== 'error') {
146146
// removed type argument from init method

packages/contentstack-utilities/src/helpers.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ export const validatePath = (input: string) => {
5454
export const escapeRegExp = (str: string) => str?.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
5555

5656
// To remove the relative path
57-
export const sanitizePath = (str: string) => str?.replace(/^(\.\.(\/|\\|$))+/, '');
57+
export const sanitizePath = (str: string) => {
58+
const decodedStr = decodeURIComponent(str);
59+
return decodedStr
60+
?.replace(/^([\/\\]){2,}/, "./") // Normalize leading slashes/backslashes to ''
61+
.replace(/[\/\\]+/g, "/") // Replace multiple slashes/backslashes with a single '/'
62+
.replace(/(\.\.(\/|\\|$))+/g, ""); // Remove directory traversal (../ or ..\)
63+
};
5864

5965
// To validate the UIDs of assets
6066
export const validateUids = (uid) => /^[a-zA-Z0-9]+$/.test(uid);

0 commit comments

Comments
 (0)