New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
format_from_string and string_of_format #7799
Comments
Comment author: @gasche Indeed, it appears that the Scanf.format_of_string implementation, which has its own implementation of string escaping, is buggy. The following would work correctly: let format_from_string s fmt = I can fix this in the stdlib, but you can also use the code above as a workaround for yourself. |
Comment author: @gasche Note: since the Big Format Change of 4.02, there is also a function CamlinternalFormat.format_of_string_format, with the same interface as Scanf.format_from_string, which I believe behaves correctly -- its implementation is more directly than Scanf's. CamlinternalFormat functions are internal and not meant for external usage, but this is also a workaround. I'm curious, what is your use-case for using these functions? |
Comment author: gmelquiond Sometimes, operator '^^' is not sufficient to manipulate format strings, so you have to go back to plain strings to benefit from a lot more functions. In fact, unless I missed it, there is not even a function that takes a nonliteral string free of '%' and turns it into a plain format string (except for format_of_string, obviously). Anyway, thanks for the suggestion of using Scanf.sscanf_format. It is much nicer than the one I had come up for Why3, which was to escape all the backslashes before feeding it to format_from_string. |
Comment author: @nojb Just as a follow-up, Scanf.format_from_string actually uses CamlinternalFormat.format_of_string_format. The problem is the implementation of escaping in Scanf.string_to_String which only escapes double quotes. I submitted a PR with a variant of the fix suggested by Gabriel: |
Comment author: @nojb PR merged |
Original bug ID: 7799
Reporter: gmelquiond
Assigned to: @nojb
Status: resolved (set by @nojb on 2018-06-07T07:29:19Z)
Resolution: fixed
Priority: normal
Severity: major
Version: 4.06.1
Category: standard library
Monitored by: @nojb @yakobowski
Bug description
I naively expect the functions format_from_string and string_of_format to be inverse of each other. But they are not, which leads to some obscure bugs when trying to use them. As far as I can tell, it is because format_from_string escapes double quotes but not backslashes before parsing the string. This is reproducible with all the versions of OCaml I have tested, from 4.02.3 to 4.07-beta.
Steps to reproduce
let test s = ignore (Scanf.format_from_string (string_of_format s) s);;
test "%s/%a";; (* OK )
test "\ ";; ( Exception: Scanf.Scan_failure "illegal escape character ' '". )
test "\x";; ( Exception: Scanf.Scan_failure "illegal escape character '"'". )
test "\x25s";; ( Exception: Scanf.Scan_failure "bad input: format type mismatch between "%s" and "\\x25s"". )
test "\"%s";; ( Exception: Scanf.Scan_failure "bad input: format type mismatch between "\\" and "\\\"%s"". )
test "\";; ( Exception: Scanf.Scan_failure "scanning of a String failed: premature end of file occurred before end of token". *)
The text was updated successfully, but these errors were encountered: