Fix #74039 is_infinite(-INF) broken when isinf not defined#2356
Fix #74039 is_infinite(-INF) broken when isinf not defined#2356c960657 wants to merge 2 commits intophp:PHP-7.0from c960657:is-infinite-5.6
Conversation
|
This is targeting a security fix only branch. |
|
I have pushed a new version against the PHP-7.0 branch. |
|
This should have a bug on bugs.php.net for reference, and you should not update the news file in the PR - the merger does that. |
|
I have now removed the NEWS entry, and also added some tests for |
|
@c960657 please open a bug on bugs.php.net |
|
Sorry, it's here: https://bugs.php.net/bug.php?id=74039 |
|
@c960657 Can you have a look at master, it needs a different patch because file names have changed (or maybe no patch) ? |
|
The patch isn't wrong (and this line should be changed), but I think the actual problem is that we check for isinf and isnan as functions in configure, while IIRC they are spec'd as macros. musl probably only has them as macros, so HAVE_ISINF and HAVE_ISNAN end up not being set. Without mucking with configure, we can probably work around this with a simple |
|
That makes sense, I was a bit confused about the whole thing, especially the comment that says it's required by C99. |
The isnan() and isinf() are C99 macros not functions.
|
I have pushed a fix inspired by this. But I really have no clue about what I am doing and how to test it, so if it isn't quite right, I hope I can pass on the torch to someone else. |
|
|
|
See also: https://bugs.php.net/bug.php?id=73954 |
| #define HAVE_ISNAN 1 | ||
| #define HAVE_ISINF 1 | ||
| #define HAVE_ISFINITE 1 | ||
| #define HAVE_DECL_ISNAN 1 |
There was a problem hiding this comment.
Is renaming these constants strictly necessary?
|
Merged via 9ea0949 with tests separated out in a separate file. Thanks! |
|
…huh, |
|
@TazeTSchnitzel NaNs do have a sign bit, though it's not usually considered to be relevant. What confuses me here is why |
|
@nikic Presumably. My first thought was maybe it's doing something like |
|
Relevant code is this: php-src/Zend/zend_exceptions.c Lines 522 to 530 in 31332d0 Is there something wrong with |
|
@TazeTSchnitzel Nice catch! Looks like That still leaves the question of why we're seeing this issue only after applying this patch. |
|
I'm investigating on the same test fail recently still happening on AppVeyor. In this regard, i've found these two topics https://blogs.msdn.microsoft.com/oldnewthing/20130221-00/?p=5183/ Specifically AppVeyor, and what i get locally is -nan(ind), which is an indefinite NAN :) When debugging through, it is something that the argument contains right when it has been parsed. For the output however, it is different. In the smart string API, we check for zend_isnan() and place the hardcoded NAN, while a system routine would of course output the precise representation, Plus, representation nan(ind) as is somewhat different from what the older MSDN blog post refers to as 1#IND. So that's regarding all the possible types of NAN and INF :) In the Windows build, we seem to explicitly create this exact kind of NAN with php_get_nan(). Additionally, the other part is about the compiler flags and different compilers. Additionally, it comes to the concrete FPU which might create a different kind of nan or infinity. In PHP, we seem not to care about these differences, there it's simply a NAN. As for me - the conclusion is, that as long as we don't really care about finer NAN types and use the system routine for string conversion, and we cannot simply use is_nan() as in this case with the type hint conversion check, it is valid to simply care about the exception thrown and maybe check that the word NAN is present. Thanks. |
We could change the test, but I'm not sure the test is really the problem here. The PHP language is supposed to present only one kind of NAN. Internally it can be whatever we want, but these details shouldn't leak through into stacktraces and things. |
|
Yeah, that would be clean of course, if the corresponding place could be moved to smart string API. I was more about illustrating, that the issue is not about type hints or math, how it looked like, but just the output routine. Were it possible to replace the output routine, so we'd be fine as well. Otherwise, fixing the test were sufficient, IMHO. Thanks. |
|
I think this PR can be given the next run, the conversion routine is replaced and everything seems OK. Thanks. |
|
We still need to understand how/why this PR changed the specific NAN value that the NAN constant returns -- it shouldn't have an impact on that. |
|
Aha. So, revert the macro name change, and all is well. (You could keep that part, but it's probably needless effort. For one thing, you might get merge conflicts in master where the NaN code has been moved around.) |
|
The macro name comes from autoconf. The only change necessary here is to make the same change in ext/standard/config.m4 as was done in Zend/config.m4. |
|
What's the reason for changing it (the macro name, I mean) in the first place? Maybe I'm misunderstanding something. |
|
Relanded as 714d825 with the extra change in ext/standard/config.m4. |
* php/master: (149 commits) Fixed bug #61471 Add #ifndef restrict Fix detection of isnan and isinf ReflectionGenerator now sends ReflectionException as expected use some dynamically generated NAN as well rework fd521a2 to simplify for master, see github php#2356 switch to smart str conversion routine to hide exact NAN type Revert "Fix detection of isnan and isinf" Fix detection of isnan and isinf Fix bug #73954 Implement Parameter Type Widening RFC Add UPGRADING notes for deprecations Deprecate each() Deprecate assert() with string argument Deprecate mbstring.func_overload Deprecate track_errors / $php_errormsg Deprecate mb_parse_str() without second argument Deprecate parse_str() without second argument Deprecate (unset) Deprecate __autoload() ...
is_infinite()is broken in the PHP binary included in Alpine Linux. It returns TRUE foris_infinite(INF), but FALSE foris_infinite(-INF).I believe to have fixed the problem, but I know virtually nothing about C or the PHP source, so bear with me :-)