paulscherrerinstitute / StreamDevice

EPICS Driver for message based I/O
GNU General Public License v3.0
28 stars 42 forks source link

Not interpreted format conversions #7

Closed krisztianloki closed 6 years ago

krisztianloki commented 6 years ago

There are cases when the format conversion is not interpreted as a format conversion. For example the following protocol will not match "@001ACKparseme" but will match "@001ACK%s".

wont_work { prefix = "@" "%3c" "ACK"; in $prefix "%s"; }

The "%s" will be interpreted as literal '%' followed by 's'.

I will create a pull request with a proposed fix.

dirk-zimoch commented 6 years ago

Can you briefly explain why this is so? (To save me the effort to repeat all your work.)

krisztianloki commented 6 years ago

It may not be 100% correct, but this is what I think happens:

Encoding a format involves replacing it with binary encoded information that contains a NULL byte. This null byte terminates the search for subsequent formats. This means that if the encoding is done when the recursion depth is greater than 0, no format will be recognized as such when the recursion depth decreases.

A real life manifestation of this bug:

wont_work { prefix = "@" "%3c" "ACK"; in $prefix "%s"; }

The "%s" will be interpreted as literal '%' followed by 's'. What happens here is that the variable $prefix will be replaced (by recursively calling compileString()) with "@%3cACK" in the first step and in the second step the format conversion will be replaced with a binary encoding (sg like "<03>3c<00>..."). That NUL byte will cause the search for '%' (in the parent compileString()) to stop, leaving the "%s" intact.

The fix is simple; defer the format encode until everything else is done.

dirk-zimoch commented 6 years ago

Thanks. Please allow me some time for my own tests.

dirk-zimoch commented 6 years ago

Interestingly this only happens when prefix contains a format.

krisztianloki commented 6 years ago

Yes, because the "string" that replaces a format contains a NULL byte.