Skip to content

Commit 2224a02

Browse files
author
Ankit Saini
authored
Merge pull request #448 from postmanlabs/issue-248
Use quoteType everywhere in curl, not just in the url
2 parents c4db059 + b8cda39 commit 2224a02

File tree

3 files changed

+60
-20
lines changed

3 files changed

+60
-20
lines changed

codegens/curl/lib/index.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ self = module.exports = {
2323
format = options.longFormat;
2424
trim = options.trimRequestBody;
2525
silent = options.silent;
26-
url = getUrlStringfromUrlObject(request.url);
2726
quoteType = options.quoteType === 'single' ? '\'' : '"';
27+
url = getUrlStringfromUrlObject(request.url, quoteType);
2828

2929
snippet = silent ? `curl ${form('-s', format)}` : 'curl';
3030

@@ -72,14 +72,14 @@ self = module.exports = {
7272
if (!header.key) {
7373
return;
7474
}
75-
snippet += indent + `${form('-H', format)} '${sanitize(header.key, true)}`;
75+
snippet += indent + `${form('-H', format)} ${quoteType}${sanitize(header.key, true, quoteType)}`;
7676
// If the header value is an empty string then add a semicolon after key
7777
// otherwise the header would be ignored by curl
7878
if (header.value) {
79-
snippet += `: ${sanitize(header.value)}'`;
79+
snippet += `: ${sanitize(header.value, false, quoteType)}${quoteType}`;
8080
}
8181
else {
82-
snippet += ';\'';
82+
snippet += ';' + quoteType;
8383
}
8484
});
8585
}
@@ -130,12 +130,13 @@ self = module.exports = {
130130
// Using the long form below without considering the longFormat option,
131131
// to generate more accurate and correct snippet
132132
snippet += indent + '--data-urlencode';
133-
snippet += ` '${sanitize(data.key, trim)}=${sanitize(data.value, trim)}'`;
133+
snippet += ` ${quoteType}${sanitize(data.key, trim, quoteType)}=` +
134+
`${sanitize(data.value, trim, quoteType)}${quoteType}`;
134135
}
135136
});
136137
break;
137138
case 'raw':
138-
snippet += indent + `--data-raw '${sanitize(body.raw.toString(), trim)}'`;
139+
snippet += indent + `--data-raw ${quoteType}${sanitize(body.raw.toString(), trim, quoteType)}${quoteType}`;
139140
break;
140141
case 'graphql':
141142
// eslint-disable-next-line no-case-declarations
@@ -147,35 +148,38 @@ self = module.exports = {
147148
catch (e) {
148149
graphqlVariables = {};
149150
}
150-
snippet += indent + `--data-raw '${sanitize(JSON.stringify({
151+
snippet += indent + `--data-raw ${quoteType}${sanitize(JSON.stringify({
151152
query: query,
152153
variables: graphqlVariables
153-
}), trim)}'`;
154+
}), trim, quoteType)}${quoteType}`;
154155
break;
155156
case 'formdata':
156157
_.forEach(body.formdata, function (data) {
157158
if (!(data.disabled)) {
158159
if (data.type === 'file') {
159160
snippet += indent + `${form('-F', format)}`;
160-
snippet += ` '${sanitize(data.key, trim)}=@"${sanitize(data.src, trim, true, true)}"'`;
161+
snippet += ` ${quoteType}${sanitize(data.key, trim, quoteType)}=` +
162+
`${sanitize(`@"${sanitize(data.src, trim, '"', true)}"`, trim, quoteType, quoteType === '"')}`;
163+
snippet += quoteType;
161164
}
162165
else {
163166
snippet += indent + `${form('-F', format)}`;
164-
snippet += ` '${sanitize(data.key, trim)}="${sanitize(data.value, trim, true, true)}"`;
167+
snippet += ` ${quoteType}${sanitize(data.key, trim, quoteType)}=` +
168+
sanitize(`"${sanitize(data.value, trim, '"', true)}"`, trim, quoteType, quoteType === '"');
165169
if (data.contentType) {
166170
snippet += `;type=${data.contentType}`;
167171
}
168-
snippet += '\'';
172+
snippet += quoteType;
169173
}
170174
}
171175
});
172176
break;
173177
case 'file':
174178
snippet += indent + '--data-binary';
175-
snippet += ` '@${sanitize(body[body.mode].src, trim)}'`;
179+
snippet += ` ${quoteType}@${sanitize(body[body.mode].src, trim)}${quoteType}`;
176180
break;
177181
default:
178-
snippet += `${form('-d', format)} ''`;
182+
snippet += `${form('-d', format)} ${quoteType}${quoteType}`;
179183
}
180184
}
181185
}

codegens/curl/lib/util.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ var self = module.exports = {
55
*
66
* @param {String} inputString
77
* @param {Boolean} [trim] - indicates whether to trim string or not
8-
* @param {Boolean} [doubleQuotes] - indicates whether to escape double quotes(") and backslash(\\)
8+
* @param {Boolean} [quoteType] - indicates which quoteType has to be escaped
99
* @param {Boolean} [backSlash] - indicates whether to escape backslash(\\)
1010
* @returns {String}
1111
*/
12-
sanitize: function (inputString, trim, doubleQuotes, backSlash) {
12+
sanitize: function (inputString, trim, quoteType, backSlash) {
1313
if (typeof inputString !== 'string') {
1414
return '';
1515
}
@@ -18,12 +18,14 @@ var self = module.exports = {
1818
inputString = inputString.replace(/\\/g, '\\\\');
1919
}
2020

21-
if (doubleQuotes) {
21+
if (quoteType === '"') {
2222
inputString = inputString.replace(/"/g, '\\"');
2323
}
24+
else if (quoteType === '\'') {
25+
// for curl escaping of single quotes inside single quotes involves changing of ' to '\''
26+
inputString = inputString.replace(/'/g, "'\\''"); // eslint-disable-line quotes
27+
}
2428

25-
// for curl escaping of single quotes inside single quotes involves changing of ' to '\''
26-
inputString = inputString.replace(/'/g, "'\\''"); // eslint-disable-line quotes
2729
return trim ? inputString.trim() : inputString;
2830
},
2931

@@ -126,12 +128,13 @@ var self = module.exports = {
126128
/**
127129
*
128130
* @param {*} urlObject The request sdk request.url object
131+
* @param {boolean} quoteType The user given quoteType
129132
* @returns {String} The final string after parsing all the parameters of the url including
130133
* protocol, auth, host, port, path, query, hash
131134
* This will be used because the url.toString() method returned the URL with non encoded query string
132135
* and hence a manual call is made to getQueryString() method with encode option set as true.
133136
*/
134-
getUrlStringfromUrlObject: function (urlObject) {
137+
getUrlStringfromUrlObject: function (urlObject, quoteType) {
135138
var url = '';
136139
if (!urlObject) {
137140
return url;
@@ -161,7 +164,7 @@ var self = module.exports = {
161164
url += '#' + urlObject.hash;
162165
}
163166

164-
return self.sanitize(url);
167+
return self.sanitize(url, false, quoteType);
165168
},
166169

167170
/**

codegens/curl/test/unit/convert.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,39 @@ describe('curl convert function', function () {
466466
});
467467
});
468468

469+
it('should generate valid snippets when quoteType is "double"', function () {
470+
// url = https://a"b'c.com/'d/"e
471+
var request = new sdk.Request({
472+
'method': 'POST',
473+
'body': {
474+
'mode': 'formdata',
475+
'formdata': [
476+
{
477+
'key': 'json',
478+
'value': '{"hello": "world"}',
479+
'contentType': 'application/json',
480+
'type': 'text'
481+
}
482+
]
483+
},
484+
'url': {
485+
'raw': "https://a\"b'c.com/'d/\"e", // eslint-disable-line quotes
486+
'host': [
487+
'a"b\'c',
488+
'com'
489+
]
490+
}
491+
});
492+
convert(request, {quoteType: 'double'}, function (error, snippet) {
493+
if (error) {
494+
expect.fail(null, null, error);
495+
}
496+
497+
expect(snippet).to.include('"a\\"b\'c.com"');
498+
expect(snippet).to.include('"json=\\"{\\\\\\"hello\\\\\\": \\\\\\"world\\\\\\"}\\";type=application/json"');
499+
});
500+
});
501+
469502
describe('getUrlStringfromUrlObject function', function () {
470503
var rawUrl, urlObject, outputUrlString;
471504

0 commit comments

Comments
 (0)