php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74450 Fetching the value of a constant triggers inconsistent behaviour
Submitted: 2017-04-15 21:27 UTC Modified: 2017-04-15 21:44 UTC
From: diego dot bindart at gmail dot com Assigned:
Status: Open Package: Apache2 related
PHP Version: 7.0.18 OS: Linux Mint 18
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-04-15 21:27 UTC] diego dot bindart at gmail dot com
Description:
------------
I define a constant as case-insenstive and then define a capitalization variation of the same constant. In between defines I echo the value of the constant *using the case-sensitive capitalization*.

In the CLI it works as expected, but testing in the apache server gives me the right anser only once, and then a different answers on succesive page reloads. The same happens if instead of echoing I assign the constant value to a variable (e.g. $var = SOME_CONST).

Tested on Chrome, Opera and Firefox, using Apache 2.4.18 Ubuntu.

Steps to reproduce:
* execute the code below, as given, in a web server. You should get (as expected): 12
* reload the page (might need to do this several times) and you get instead: 11

----------------
Other things to note that I tested:

* it works as expected in the command line
* if you don't echo SOME_CONST before defining the case-sensitive variation, it works as expected
* if you echo SOME_const (or any other capitalization variation) there's no bug either
* sometimes it needs one reload and sometimes many (never more than 3 or 4, though)
* after you get the bug, comment the first echo and you'll get the right result again; remove the comment and you get the bug again after few reloads
* if I print the defined constants I see both constants with the right values (namely 1 and 2)

Test script:
---------------
define('sOmE_CoNsT', 1, true);
echo SOME_CONST; // Prints 1

define('SOME_CONST', 2);
echo SOME_CONST; // Prints 2

Expected result:
----------------
Consistently prints "12" on successive page loads

Actual result:
--------------
Prints "12" the first few times, then "11" on successive page reloads

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-04-15 21:30 UTC] diego dot bindart at gmail dot com
-Summary: Fetching constant value triggers inconsistent behaviour +Summary: Fetching the value of a constant triggers inconsistent behaviour
 [2017-04-15 21:30 UTC] diego dot bindart at gmail dot com
Editted the title to make the issue clearer
 [2017-04-15 21:37 UTC] nikic@php.net
The reason you're seeing this specific behavior is a combination of runtime caching and literal compaction. You're seeing this only with Apache, because that's where you have opcache enabled, which performs the deduplication. Here is a way to reproduce this without opcache as well: https://3v4l.org/L6nCp

Anyway, I believe the bug here is that we currently do not check whether a case-insensitive constant with the same name already exists. This should be giving a "constant already defined" error instead.
 [2017-04-15 21:44 UTC] nikic@php.net
Also, I believe that the reason why we're currently not checking for this, is that while the direction case-insensitive -> case-sensitive is simple (we can check whether the lower-cased variant exists when defining the case-sensitive constant), the direction case-sensitive -> case-insensitive is not (we cannot check whether a case-variant exists, without storing additional information.)

This is probably a good time to create an RFC for deprecation and removal of case-insensitive constants (with null/true/false special-cased). Notably HHVM already doesn't support them, which tells us that at least no open-source software of any significance makes use of them.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC