fix: Adjust Bruno grammar to allow quoting some special characters in names query parameters

Automatically quote query parameter keys if they contain characters sensitive for bru syntax: ':', '"', '{', '}' or ' '.
Quoted keys stored in .bru files now support escaping, so it is possible to store keys that themselves contain '"' character.

Fixes #3037
Fixes #2810
Fixes #2878
This commit is contained in:
Mateusz Pietryga
2024-09-05 18:59:37 +02:00
parent fee631d496
commit b02f6b61ee
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
@@ -229,6 +235,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() : '';
},
@@ -280,6 +294,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",