fix: query parameters containing a colon (:) are not parsed correctly when changed

Adjust Bruno grammar so that dictionary key may optionally be quoted. Automatically quote query parameter keys if they contain ':' or '"'.
Quoted keys stored in .bru files now support escaping, so it is possible to store keys that themselves contain '"' character.
This commit is contained in:
Mateusz Pietryga 2024-09-05 18:59:37 +02:00
parent 4ef5534d41
commit d64dffe7fa
No known key found for this signature in database
GPG Key ID: 549A107FB8327670
4 changed files with 46 additions and 4 deletions

View File

@ -43,8 +43,14 @@ const grammar = ohm.grammar(`Bru {
// Dictionary Blocks
dictionary = st* "{" pairlist? tagend
pairlist = optionalnl* pair (~tagend stnl* pair)* (~tagend space)*
pair = st* key st* ":" st* value st*
key = keychar*
pair = st* (quoted_key | key) st* ":" st* value st*
disable_char = "~"
quote_char = "\\""
esc_char = "\\\\"
esc_quote_char = esc_char quote_char
quoted_key_char = ~(quote_char | esc_quote_char | nl) any
quoted_key = disable_char? quote_char (esc_quote_char | quoted_key_char)* quote_char
key = keychar+
value = multilinetextblock | valuechar*
// Dictionary for Assert Block
@ -213,6 +219,14 @@ const sem = grammar.createSemantics().addAttribute('ast', {
res[key.ast] = value.ast ? value.ast.trim() : '';
return res;
},
esc_quote_char(_1, quote) {
// unescape
return quote.sourceString;
},
quoted_key(disabled, _1, chars, _2) {
// unquote
return (disabled? disabled.sourceString : "") + chars.ast.join("");
},
key(chars) {
return chars.sourceString ? chars.sourceString.trim() : '';
},
@ -264,6 +278,9 @@ const sem = grammar.createSemantics().addAttribute('ast', {
tagend(_1, _2) {
return '';
},
_terminal(){
return this.sourceString;
},
_iter(...elements) {
return elements.map((e) => e.ast);
},

View File

@ -4,6 +4,10 @@ const { indentString } = require('../../v1/src/utils');
const enabled = (items = []) => items.filter((item) => item.enabled);
const disabled = (items = []) => items.filter((item) => !item.enabled);
const quoteKey = (key) => {
const quotableChars = [':', '"', '{', '}', ' '];
return quotableChars.some(char => key.includes(char)) ? ('"' + key.replaceAll('"', '\\"') + '"') : key;
}
// remove the last line if two new lines are found
const stripLastLine = (text) => {
@ -71,7 +75,7 @@ const jsonToBru = (json) => {
if (enabled(queryParams).length) {
bru += `\n${indentString(
enabled(queryParams)
.map((item) => `${item.name}: ${item.value}`)
.map((item) => `${quoteKey(item.name)}: ${item.value}`)
.join('\n')
)}`;
}
@ -79,7 +83,7 @@ const jsonToBru = (json) => {
if (disabled(queryParams).length) {
bru += `\n${indentString(
disabled(queryParams)
.map((item) => `~${item.name}: ${item.value}`)
.map((item) => `~${quoteKey(item.name)}: ${item.value}`)
.join('\n')
)}`;
}

View File

@ -13,6 +13,9 @@ get {
params:query {
apiKey: secret
numbers: 998877665
"colon:parameter": is allowed
"nested escaped \"quote\"": is allowed
~"disabled:colon:parameter": is allowed
~message: hello
}

View File

@ -23,6 +23,24 @@
"type": "query",
"enabled": true
},
{
"name" : "colon:parameter",
"value" : "is allowed",
"type": "query",
"enabled": true
},
{
"name" : "nested escaped \"quote\"",
"value" : "is allowed",
"type": "query",
"enabled": true
},
{
"name" : "disabled:colon:parameter",
"value" : "is allowed",
"type": "query",
"enabled": false
},
{
"name": "message",
"value": "hello",