diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index 5a489fa1..23542c1e 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -120,8 +120,8 @@ function splitCommands(rawData: string): string[] { const inQuote = inSingleQuote || inDoubleQuote || inDollarQuote; - // Split on ;, newline, or CRLF when not inside quotes - if (!inQuote && (ch === ';' || ch === '\n' || (ch === '\r' && next === '\n'))) { + // Split on ;, newline, or CRLF when not inside quotes and not escaped + if (!inQuote && !isEscaped(i) && (ch === ';' || ch === '\n' || (ch === '\r' && next === '\n'))) { if (ch === '\r') i++; // Skip the \n in \r\n if (current.trim()) { commands.push(current.trim()); diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts index df7e712f..3c986817 100644 --- a/plugins/importer-curl/tests/index.test.ts +++ b/plugins/importer-curl/tests/index.test.ts @@ -599,6 +599,26 @@ describe('importer-curl', () => { }); }); + test('Does not split on escaped semicolon outside quotes', () => { + // In shell, \; is a literal semicolon and should not split commands. + // This should be treated as a single curl command with the URL "https://yaak.app?a=1;b=2" + expect( + convertCurl('curl https://yaak.app?a=1\\;b=2'), + ).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + urlParameters: [ + { name: 'a', value: '1;b=2', enabled: true }, + ], + }), + ], + }, + }); + }); + test('Imports multipart form data with text-only fields from --data-raw', () => { const curlCommand = `curl 'http://example.com/api' \ -H 'Content-Type: multipart/form-data; boundary=----FormBoundary123' \