diff --git a/packages/bruno-app/src/utils/curl/curl-to-json.js b/packages/bruno-app/src/utils/curl/curl-to-json.js index f571c56b3..aace9916a 100644 --- a/packages/bruno-app/src/utils/curl/curl-to-json.js +++ b/packages/bruno-app/src/utils/curl/curl-to-json.js @@ -173,8 +173,8 @@ const curlToJson = (curlCommand) => { requestJson.headers = {}; } requestJson.headers['Content-Type'] = 'multipart/form-data'; - } else if (request.isDataBinary) { - Object.assign(requestJson, getFilesString(request)); + } else if (request.isDataBinary && (typeof request.data === 'string' && request.data.startsWith('@'))) { + Object.assign(requestJson, getFilesString(request)); // file case } else if (typeof request.data === 'string' || typeof request.data === 'number') { Object.assign(requestJson, getDataString(request)); } diff --git a/packages/bruno-app/src/utils/curl/parse-curl.js b/packages/bruno-app/src/utils/curl/parse-curl.js index 24dd9334a..3dd81fa81 100644 --- a/packages/bruno-app/src/utils/curl/parse-curl.js +++ b/packages/bruno-app/src/utils/curl/parse-curl.js @@ -522,8 +522,8 @@ const cleanRequest = (request) => { * Handles escape sequences, line continuations, and method concatenation */ const cleanCurlCommand = (curlCommand) => { - // Handle escape sequences - curlCommand = curlCommand.replace(/\$('.*')/g, (match, group) => group); + // Handle bash ANSI $'..' escapes by decoding common sequences + curlCommand = curlCommand.replace(/\$'((?:\\.|[^'])*)'/g, (match, group) => quoteForShell(decodeAnsiEscapes(group))); // Convert escaped single quotes to shell quote pattern curlCommand = curlCommand.replace(/\\'(?!')/g, '\'\\\'\''); // Fix concatenated HTTP methods @@ -555,4 +555,33 @@ const fixConcatenatedMethods = (command) => { return command; }; +/** + * Decode bash ANSI $'..' escape sequences + */ +const decodeAnsiEscapes = (value) => { + return value.replace(/\\(\\|'|n|r|t|v|f|a|b|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4})/g, (match, seq) => { + switch (seq[0]) { + case '\\': return '\\'; + case '\'': return '\''; + case 'n': return '\n'; + case 'r': return '\r'; + case 't': return '\t'; + case 'v': return '\v'; + case 'f': return '\f'; + case 'a': return '\x07'; + case 'b': return '\b'; + case 'x': return String.fromCharCode(parseInt(seq.slice(1), 16)); + case 'u': return String.fromCharCode(parseInt(seq.slice(1), 16)); + default: return match; + } + }); +}; + +/** + * Wrap value in single quotes while preserving embedded single quotes + */ +const quoteForShell = (value) => { + return `'${value.replace(/'/g, '\'\\\'\'')}'`; +}; + export default parseCurlCommand;