From: cleong at nflc dot org Operating system: Windows 2000 PHP version: 4.3.7 PHP Bug Type: Filesystem function related Bug description: Thread safty issue with stream_wrapper_register?
Description: ------------ On Windows 2000, with PHP running as an Apache module, stream_wrapper_register() would fail when there are concurent scripts using that function. It would either fail without an error message or causes the Apache process to crash. When there's just one script running the function works fine. To reproduce this bug, open a couple browser windows and go to the reproduce code in each. I can get around the bug by generating a random class name and protocol name everytime (using eval for the class definition). Reproduce code: --------------- <? // example class taken from manual class VariableStream { var $position; var $varname; function stream_open($path, $mode, $options, &$opened_path) { $url = parse_url($path); $this->varname = $url["host"]; $this->position = 0; return true; } function stream_read($count) { $ret = substr($GLOBALS[$this->varname], $this->position, $count); $this->position += strlen($ret); return $ret; } function stream_write($data) { $left = substr($GLOBALS[$this->varname], 0, $this->position); $right = substr($GLOBALS[$this->varname], $this->position + strlen($data)); $GLOBALS[$this->varname] = $left . $data . $right; $this->position += strlen($data); return strlen($data); } function stream_tell() { return $this->position; } function stream_eof() { return $this->position >= strlen($GLOBALS[$this->varname]); } function stream_seek($offset, $whence) { switch ($whence) { case SEEK_SET: if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) { $this->position = $offset; return true; } else { return false; } break; case SEEK_CUR: if ($offset >= 0) { $this->position += $offset; return true; } else { return false; } break; case SEEK_END: if (strlen($GLOBALS[$this->varname]) + $offset >= 0) { $this->position = strlen($GLOBALS[$this->varname]) + $offset; return true; } else { return false; } break; default: return false; } } } stream_wrapper_register("var", "VariableStream") or die("Failed to register protocol"); $myvar = ""; $fp = fopen("var://myvar", "r+"); fwrite($fp, "line1\n"); fwrite($fp, "line2\n"); fwrite($fp, "line3\n"); rewind($fp); while (!feof($fp)) { echo fgets($fp); } session_write_close(); // in case auto-session is on for($i = 0; $i < 30; $i++) { // make the script run for 30 seconds sleep(1); } fclose($fp); var_dump($myvar); ?> Expected result: ---------------- Same result in each window. Actual result: -------------- While the first script is still running, the second script would say "Failed to register protocol". If you refresh the second window, sometimes it works, sometimes it causes a general protection error. -- Edit bug report at http://bugs.php.net/?id=28868&edit=1 -- Try a CVS snapshot (php4): http://bugs.php.net/fix.php?id=28868&r=trysnapshot4 Try a CVS snapshot (php5): http://bugs.php.net/fix.php?id=28868&r=trysnapshot5 Fixed in CVS: http://bugs.php.net/fix.php?id=28868&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=28868&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=28868&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=28868&r=needscript Try newer version: http://bugs.php.net/fix.php?id=28868&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=28868&r=support Expected behavior: http://bugs.php.net/fix.php?id=28868&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=28868&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=28868&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=28868&r=globals PHP 3 support discontinued: http://bugs.php.net/fix.php?id=28868&r=php3 Daylight Savings: http://bugs.php.net/fix.php?id=28868&r=dst IIS Stability: http://bugs.php.net/fix.php?id=28868&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=28868&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=28868&r=float