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

fix: escape arguments containing spaces #982

Merged
merged 15 commits into from
Jan 5, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {useEntityDetailsPick} from '@store/entityDetails';

import Colors from '@styles/Colors';

import {escapeArguments} from '@utils/escapeArguments';
import {externalLinks} from '@utils/externalLinks';
import {displayDefaultNotificationFlow} from '@utils/notification';
import {prettifyArguments} from '@utils/prettifyArguments';
Expand All @@ -45,15 +46,17 @@ const Arguments: React.FC<ArgumentsProps> = ({readOnly}) => {
const [updateTest] = useUpdateTestMutation();

const entityArgs = details.executionRequest?.args || [];
const initialArgs = useMemo(() => entityArgs?.join('\n') || '', [entityArgs]);
const initialArgs = useMemo(() => escapeArguments(entityArgs)?.join('\n') || '', [entityArgs]);

const currentArgs = Form.useWatch('args', form) || '';
const currentArgsInline = currentArgs.replace(/\s+/g, ' ').trim();
const isPrettified = useMemo(() => currentArgs === prettifyArguments(currentArgs), [currentArgs]);

const onSaveForm = () => {
const values = form.getFieldsValue();
const argVal = values.args?.trim().split('\n').filter(Boolean) || [];
const prettifiedArgs = useMemo(() => prettifyArguments(currentArgs), [currentArgs]);
const currentArgsInline = useMemo(() => prettifiedArgs.replace(/\n+/g, ' '), [prettifiedArgs]);

const isPrettified = currentArgs === prettifiedArgs;

const onSaveForm = async () => {
const argVal = currentArgs?.trim().split('\n').filter(Boolean) || [];

// Reset the form when there is no actual change
if (argVal.join('\n') === initialArgs) {
Expand All @@ -68,14 +71,13 @@ const Arguments: React.FC<ArgumentsProps> = ({readOnly}) => {
},
};

return updateTest({
const res = await updateTest({
id: details.name,
data: successRecord,
})
.then(displayDefaultNotificationFlow)
.then(() => {
notificationCall('passed', 'Variables were successfully updated.');
});
});

displayDefaultNotificationFlow(res);
notificationCall('passed', 'Variables were successfully updated.');
};

const onPrettify = useLastCallback(() => form.setFieldValue('args', prettifyArguments(currentArgs)));
Expand Down
29 changes: 29 additions & 0 deletions packages/web/src/utils/escapeArguments.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {escapeArguments} from './escapeArguments';

describe('utils', () => {
describe('escapeArguments', () => {
it('should handle empty array', () => {
expect(escapeArguments([])).toEqual([]);
});

it('should handle array with one argument', () => {
expect(escapeArguments(['abc'])).toEqual(['abc']);
});

it('should handle array with multiple arguments', () => {
expect(escapeArguments(['abc', 'def'])).toEqual(['abc', 'def']);
});

it('should handle array with multiple arguments with spaces', () => {
expect(escapeArguments(['ab c', 'de f'])).toEqual(['"ab c"', '"de f"']);
});

it('should handle array with multiple arguments with quotes', () => {
expect(escapeArguments(['ab"c', 'de"f'])).toEqual(['ab\\"c', 'de\\"f']);
});

it('should handle array with multiple arguments with spaces and quotes', () => {
expect(escapeArguments(['ab"c', 'de f'])).toEqual(['ab\\"c', '"de f"']);
});
});
});
7 changes: 7 additions & 0 deletions packages/web/src/utils/escapeArguments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const escapeArguments = (args: string[]) => {
return args.map(arg => {
const escapedArg = arg.replace(/(["'`])/g, '\\$1');
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed

return /\s/.test(escapedArg) ? `"${escapedArg.replace(/\\'/g, "'")}"` : escapedArg;
});
};
Loading