From:             d-alvarez at gmx dot de
Operating system: GNU/Linux 2.4.21-144-default
PHP version:      4.3.4
PHP Bug Type:     Reproducible crash
Bug description:  Concurrent upload ignored when processing is synchronized

Description:
------------
Take any html page that uploads a file using HTTP post.
It does not matter what the receiving script does, because
this issue is only related to the interpreter. A page as 
simple as the following suffices to reproduce the problem:

<html><body>
<form method="post" enctype="multipart/form-data"
      action="http://www.somesite.org/somescript.php";>
<input name="somefile" type=file><input type="submit">
</form>
</body>
</html>

Change the form's action to some script on a php server.
I have placed an echo in it, so I can see more easily if 
the script is run. And, of course, it should use the file
posted, so that we can get an error if it does not find
it. You can use this:

<?php

  echo "the script has been started";

  is_uploaded_file ($somefile);
?>

Now use the html page to upload a file sufficiently large
enough for the upload to take several seconds to complete.
While the data is being submitted, load the script a second
time in another instance of your browser, and post the same
file again (in parallel to the first post running in the
background). I use a file 824 kb in size. Transmitted over
ISDN, the two posts take like two minutes of time to 
complete. The file was a zip archive.

Now, while the server is handling the two uploads concurrently, get a
listing of the directory it uses to
store the temporary files. You can watch the two
uploading files growing until both uploads complete.

[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 228
-rw-------    1 wwwrun   www        114688 2004-01-04 23:09 phpHh9HQ9
-rw-------    1 wwwrun   www        110592 2004-01-04 23:09 phpp9QIDj
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 360
-rw-------    1 wwwrun   www        180224 2004-01-04 23:10 phpHh9HQ9
-rw-------    1 wwwrun   www        180224 2004-01-04 23:10 phpp9QIDj
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 572
-rw-------    1 wwwrun   www        299008 2004-01-04 23:10 phpHh9HQ9
-rw-------    1 wwwrun   www        278528 2004-01-04 23:10 phpp9QIDj
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 1528
-rw-------    1 wwwrun   www        790528 2004-01-04 23:12 phpHh9HQ9
-rw-------    1 wwwrun   www        765952 2004-01-04 23:12 phpp9QIDj
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 1664
-rw-------    1 wwwrun   www        844067 2004-01-04 23:13 phpHh9HQ9
-rw-------    1 wwwrun   www        844067 2004-01-04 23:13 phpp9QIDj


Now, with both files being uploaded, two scripts begin
to execute, one for each file. Subsequent directory
listings will show the temporary files being deleted
as the php scripts complete.

[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 832
-rw-------    1 wwwrun   www        844067 2004-01-04 23:13 phpp9QIDj

(first file has been deleted automatically,
 because script started first has completed processing)

[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 0

(second file has been deleted automatically,
 because script started last has completed processing)


This is the situation as it should be. Now place an .htaccess file into a
directoy above the directory 
containing your script. The .htaccess file should usually
cause your browser to ask you for some realm and password, 
and then ask you to commit, e.g. by clicking an OK button.

Again, start two posts in parallel, but do not yet
commit the authorization dialogue shown to you in
response to the .htaccess file.

The files are uploaded, probably to some temporary
location in memory. While the files get uploaded, get
some listings of your temporary directory, as before.
Neither the system-global /tmp directory, nor the location
used to store temporary php files have any entries, but
the line is busy for exactly as much time as during the
post when there was no .htaccess file yet.

Probably the upload is handled differently by Apache.

[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 0

[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l /tmp
[EMAIL PROTECTED]:~/html/wcopy/datenaustausch>


Now confirm the authorization dialogue in your browser.
In Internet Explorer, you are shown a single dialogue
for both html pages. Maybe the .htaccess file per se is
irellevant here. I guess the point is that by committing
the dialogue, processing continues synchronously for both
posts. Anyway, by committing, you trigger something on
the server that causes two scripts to execute at exactly
the same time, one for each upload.

Quickly after committing, get some directory listings, as
before. You'll get something along the lines of:

[EMAIL PROTECTED]:~/html/wcopy/datenaustausch> ls -l ~/phptmp
insgesamt 32
--w-------    1 wwwrun   www         32768 2004-01-05 00:02 phpu7oZqm

The bottom line is: one file instead of two. You can
watch it growing as in the first example, but there is
no second temporary file. Furthermore, one of the scripts 
has been started immediately, without waiting for the
upload to complete. If you tried to use the file within
the script, it will barf out some error.

Ocassionally, even the second script will not complete
properly, complaining about the uploaded file being
corrupted. Probably this script is also started without
waiting for the upload to complete.




Reproduce code:
---------------
See above.

Expected result:
----------------
Two files being uploaded, and two instances of the script
being run after the uploads have completed.

Actual result:
--------------
Only a single file being uploaded, and one instance of
the script being run before the upload is completed. 
Sometimes even the second instance of the script is run
while the upload is still in progress.

-- 
Edit bug report at http://bugs.php.net/?id=26788&edit=1
-- 
Try a CVS snapshot (php4):  http://bugs.php.net/fix.php?id=26788&r=trysnapshot4
Try a CVS snapshot (php5):  http://bugs.php.net/fix.php?id=26788&r=trysnapshot5
Fixed in CVS:               http://bugs.php.net/fix.php?id=26788&r=fixedcvs
Fixed in release:           http://bugs.php.net/fix.php?id=26788&r=alreadyfixed
Need backtrace:             http://bugs.php.net/fix.php?id=26788&r=needtrace
Need Reproduce Script:      http://bugs.php.net/fix.php?id=26788&r=needscript
Try newer version:          http://bugs.php.net/fix.php?id=26788&r=oldversion
Not developer issue:        http://bugs.php.net/fix.php?id=26788&r=support
Expected behavior:          http://bugs.php.net/fix.php?id=26788&r=notwrong
Not enough info:            http://bugs.php.net/fix.php?id=26788&r=notenoughinfo
Submitted twice:            http://bugs.php.net/fix.php?id=26788&r=submittedtwice
register_globals:           http://bugs.php.net/fix.php?id=26788&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=26788&r=php3
Daylight Savings:           http://bugs.php.net/fix.php?id=26788&r=dst
IIS Stability:              http://bugs.php.net/fix.php?id=26788&r=isapi
Install GNU Sed:            http://bugs.php.net/fix.php?id=26788&r=gnused
Floating point limitations: http://bugs.php.net/fix.php?id=26788&r=float

Reply via email to