PoC: php_printf: introduce %pS to replace custom specifier %S - #22930
PoC: php_printf: introduce %pS to replace custom specifier %S#22930arnaud-lb wants to merge 4 commits into
Conversation
|
cc @TimWolla @DanielEScherzer since you've suggested to use |
|
Ohhhh I like this idea a lot, will allows us to remove all of those unchecked variants too. Pinging @NattyNarwhal as we encountered a similar problem looking at |
TimWolla
left a comment
There was a problem hiding this comment.
I recently learned that passing a non-void* pointer to %p is technically UB, but all compilers just seem to accept it without warnings. Since this is not a regular printf() anyways, I very much like this hack.
|
The only other "easy" hack is some kind of macro to just cast I was wondering about proposing a way to specify custom format specifiers to gcc/clang. That I think would be very useful (i.e. don't mix up |
DanielEScherzer
left a comment
There was a problem hiding this comment.
- this should probably be highlighted as a breaking change in UPGRADING.INTERNALS - we have existing in-tree code that uses
%pdthat wouldn't break, but is the kind of thing that would break,Line 1663 in 61a190c
- what if I wanted the old behavior of
%pSor some other character afterwards? Can we add support for%pPto mean "I want %p", so that%pPSallows the old behavior, and (e.g. if%pdwas added to format something custom)%pPdwould allow the old behavior?
I was planning to not change the behavior of But maybe it's better to break this once and for all, so that new specifiers can be introduced without breaking changes in the future. Edit: It looks like that this sqlite3 code is unreachable? Apparently the
Very good point. Tried to find how the kernel addresses this, but apparently they don't. A workaround is to print the adjacent char with - php_printf("%pS", ptr);
+ php_printf("%p%c", ptr, 'S');But I like the idea of doubling - php_printf("%pS", ptr);
+ php_printf("%ppS", ptr); |
The string formater supports custom format specifiers such as
S(zend_string*), but format strings using these specifiers do not pass the compiler's type checks that are performed on functions tagged withZEND_ATTRIBUTE_FORMAT:As a result we can not use these specifiers without resorting to workarounds:
ZEND_ATTRIBUTE_FORMAT(example)Here I propose to re-introduce
%Sas%pS. The compiler will only see a%pspecifier followed by the ordinary literal characterS, so it will be happy about an argument of typezend_string*.This trick is used in the Linux kernel, and can be applied to more custom specifiers.