php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #30772 php_check_syntax collides with require_once
Submitted: 2004-11-13 10:24 UTC Modified: 2005-04-06 16:22 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: pecoes at web dot de Assigned: iliaa (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5CVS-2005-03-06 OS: *
Private report: No CVE-ID: None
 [2004-11-13 10:24 UTC] pecoes at web dot de
Description:
------------
The reproduce code is pretty straight-forward, which makes the issue look easy to avoid. My real problem, however, is more subtle:
I'm writing an extensible library. All my internal classes are __autoload'ed, but I want to treat all user-defined classes as tainted and load them manually:

Test.php:
<?php
class Tets {}  // Note the typo!
?>

bug.php:
<?php
function __autoload ($class) {
    require_once "$class.php";
}
function loadManually ($class) {
    if (!php_check_syntax("$class.php")) {
        throw new Exception("$class.php cannot be included");
    }
    // class_exists invokes __autoload and things go wrong
    if (!class_exists($class)) {
        throw new Exception("$class does not exist in $class.php");
    }
}
loadManually("Test");
?>

Reproduce code:
---------------
$file = "Test.php";
if (!php_check_syntax($file)) {
    die("$file cannot be included");
}
// the following line should do nothing!
require_once $file;

Expected result:
----------------
no crash

Actual result:
--------------
"Fatal Error: Cannot redeclare class..."
and then php(cli) crashes hard!

Patches

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-11-16 09:16 UTC] tony2001@php.net
Reproducible both with 5.0 & 5.1 branches.

Program received signal SIGSEGV, Segmentation fault.
0x00000006 in ?? ()
(gdb) bt
#0  0x00000006 in ?? ()
#1  0x00000000 in ?? ()
#2  0xbfffbf30 in ?? ()
#3  0xbfffbf68 in ?? ()
#4  0xbfffbeec in ?? ()
#5  0x00000001 in ?? ()
#6  0x08226ebb in yy_chk ()
#7  0xbfffbf68 in ?? ()
#8  0x08188964 in zif_class_exists (ht=-1073758484, return_value=0x1, this_ptr=0x8226ebb, return_value_used=-1073758360)
    at /home/dev/php-src/Zend/zend_builtin_functions.c:907
Previous frame inner to this frame (corrupt stack?)

Reproduce code could be safely reduced to this:
<?
function __autoload ($class) {
    require_once "$class.php";
}

php_check_syntax("Test.php");
class_exists("Test");
?>
 [2004-11-29 07:49 UTC] pecoes at web dot de
Hi Tony,

You haven't read my entire post. I've given *two* code samples. The *second* is the reproduce code. Please note, that my reproduce code is actually simpler, than what you have "reduced" it to.

My laymen's guess is that php_check_syntax doesn't add a script that has proven to be faulty to the list require_once and include_once maintain. The reasoning behind that is superficially seen sound. Why would you want to try again to include code that has already proven to be bad? Well, that's why I featured the "real life" sample prior to the actual reproduce code. There's a scenario, where it's impossible to avoid a new inclusion attempt, since class_exists *will* call __autoload if the class doesn't exist.

Peter
 [2005-04-06 16:22 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

After extensive code review it was determined that it would take too many engine hacks to make it work properly and the function was removed.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Aug 17 15:01:29 2024 UTC