yab
yab copied to clipboard
YAML template doesn't work with escaped characters in strings
Hi,
I defined the following yaml template:
#!/usr/bin/env yab -vvv --timeout 5000 -y
service: my-service
method: MyService::myMethod
peer: localhost:21300
thrift: ../MyThift.thrift
headers:
x-tenancy: testing
request:
params:
ownerUuid: 3e48dafa-f923-4c15-af73-7cc4f8027c19
cityId: 34
tripUuid: bfb4f0fa-6579-4b5e-8014-87825c69e89f
ownerType: INDIVIDUAL
extraPaymentData: >
{
"paymentBundle":{
"token":{
"id":"3CD6FB59914966asdasdfasdqwcasadcakcn12",
"instrumentName":null,
"network":"Visa",
"data": "{\"version\":\"EC_v1\",\"data\":\"iQxT3eQmjbO4tpbzkkBYXHtqOobbSdtpZLGhwrro80q9Ppijf1tRMU7oWIc5MCFJuzdt75m14i1gq8Nh2eYkhXnQ97kYjXONtbvo8bgbPg\/Oix9VHHQusy8laPLrUUSOuR\/kXZxerxcg4NPR+y5Cv2eTym6Rmo2U9E1QAF5wE4idAGZmWfRBEE1a1KAwYxgALdpbxTu0t8ugQtmcXQbpZ+8Z+t4f29arOkAtFRxhiiw5f8PW6S3Qrx3OjES6jhbB\/vHZV20GtitByW3Nvt0syzqrYK8wUlRdM0lU9Zm+LRUlLYjtHFKqqXWHWYUrfUdvvxB19f0uoGznY3\/4MWJtujOMHT8E5KF+c2vV2O72vCMLC49rcBgAigWtgwLjDvnkjbpHXoefaAsL70Q0\/UpoC9nteQZ5OpXW1DdaW65wrw=\"}"
}
}
}
When I try to execute this file I get the following error which originates from the yab tool:
➜ ./my-request.yaml
Failed to parse options: failed to read yaml template: yaml: line 13: did not find expected ',' or '}'
I cloned the yab repo locally and tried to debug a little bit.
The problem happens during templateargs.ProcessMap(t.Request, templateArgs) and specifically during the processing of the extraPaymentData string field. If I understand correctly since there are no templates in the string that I specified then the code should follow this conditional and be a noop:
if rendered == v {
// Avoid unmarshalling if the value did not change.
return v, nil
}
However it looks like the rendered string is missing some character escapes from the original string, for example \" and \/. Because of this the code doesn't take the Avoid unmarshalling if the value did not change path.
And then the error happens during the next step which is:
// Otherwise, unmarshal the value and return that.
var unmarshalled interface{}
err = yaml.Unmarshal([]byte(rendered), &unmarshalled)
Thanks for the detailed bug report. This is caused by the parser for template args as you pointed out. The specific issue is that when an escaped literal is found, the parser drops the fact that it's escaped,
# Anything followed by a '\' is used as-is.
escaped_lit = '\\' any @{ l = literal(data[fpc:fpc+1]) };
@abhinav Do you remember why we don't keep the escape character as part of the literal? Should we instead have an escaped literal function that's used so it can be identified and appropriately escaped?