title: JPEG files uploaded to a PHP script arrive corrupt - but not all the time
body: <p>I have a PHP script to which I upload JPEG images (through an HTML form). You can see the code <a href="http://junk.orderofthehammer.com/adm_addphoto.txt" rel="nofollow">here</a>, but I will attempt to present the relevant parts in this post. The form is declared like so:</p>
  
  <pre><code>&lt;form action="adm_addphoto.php" method="POST" enctype="multipart/form-data" name="myform"&gt;
  </code></pre>
  
  <p>The <code>MAX_FILE_SIZE</code> form field is set to 5MB:</p>
  
  <pre><code>&lt;input type="hidden" name="MAX_FILE_SIZE" value=5242880&gt;
  </code></pre>
  
  <p>The images I want to upload are about 3MB in size.</p>
  
  <p>Once it's uploaded, I turn the image file into a GD jpeg:</p>
  
  <pre><code>$filename = $_FILES['file']['tmp_name'];
  $myImage = imagecreatefromjpeg($filename);
  </code></pre>
  
  <p>Sometimes the upload works fine, and sometimes <code>imagecreatefromjpeg</code> emits warnings about the JPEG being corrupt. For example (line breaks added for readability):</p>
  
  <pre><code>Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]:
           gd-jpeg, libjpeg: recoverable error: Corrupt JPEG data:
           47 extraneous bytes before marker 0xd9 in
           /path/adm_addphoto.php on line 97
  
  Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]:
           '/tmp/phpwlSS9x' is not a valid JPEG file in
           /path/adm_addphoto.php on line 97
  </code></pre>
  
  <p>The thing is, this doesn't happen reliably. That is, if I try the same image several times in a row, sometimes it will upload successfully and sometimes there will be errors. And within the attempts that result in errors, the specifics of the error message will vary too. (With the particular photo that produced the above messages, the number of "extraneous bytes" is sometimes 47, sometimes 20, occasionally 68.)</p>
  
  <p>What might be causing the files to arrive corrupt on some attempts but not others?</p>
  
  <p>PS. I know that there is an ini setting that tells GD to try hard to work with corrupt JPEGs. But that's not the point, I want to know why the result of the upload is inconsistent.</p>
  
  <p>PPS. Here are the values of some possibly-relevant PHP ini settings:</p>
  
  <pre><code>memory_limit .......... 128M
  post_max_size ......... 8M
  file_uploads .......... On
  max_file_uploads ...... 20
  upload_max_filesize ... 128M
  upload_tmp_dir ........ no value
  </code></pre>
  
  <p>UPDATE: I added code to echo out the size and MD5 checksum of the file once it was uploaded. The size is always the correct filesize (the size of my local copy of the file). The MD5, however, varies between attempts. When the MD5 is correct (matches the MD5 of my local copy), there is no error message. When there is an error message, the MD5 is always different from expected. Also, this is just a perceived difference, but errors seemed to be occurring more frequently last night than this morning - only a minority of transfers this morning resulted in an error.</p>
  
  <p>Here are some "bad" uploads (curiously, there were a couple of uploads that gave an MD5 checksum different to that expected but did not produce errors):</p>
  
  <pre><code>                   Correct MD5: f7b9587f39c7332e62a08adf34cefbd0
  -----------------------------------------------------------------
             38 extraneous bytes: 2a28c46079071d9d2e2fd49865b35d59
                                  ce1c69f798953b201dcc35f85f3b29b4
                                  b013a0428a71adff674a46e92372d46b
             71 extraneous bytes: a271928f3559b6deaa19804704b5bcb3
             92 extraneous bytes: cab2a10ad8535addaca3b19bcb607a30
   premature end of data segment: 4514d39db1d94ab691d6da26c0832cdb
                    No error (!): 83b2e3624ddcfdeb3efc10be81631916
                                  07d0a97b21d423fdeb4c6f88d76f8cd3
  </code></pre>
  
  <p>UPDATE: In response to Andre and Pekka: Here are links to two versions of the same picture. <a href="http://junk.orderofthehammer.com/image_ftp_uploaded.jpg" rel="nofollow">This one</a> is the original copy of the image, as stored on my machine; I uploaded it the way I usually upload files to my webhosting, i.e. I used an FTP client. <a href="http://junk.orderofthehammer.com/image_php_uploaded_bad.jpg" rel="nofollow">This one</a> is the same image, uploaded using my script (but with a line added to move it to that location using <code>move_uploaded_file()</code>). The error message on that upload was "Corrupt JPEG data: 30 extraneous bytes...". You will notice that the bottom part of the image appears incorrect. I apologise for the large size of the images, but I can only use examples of the type of images that are giving me problems.</p>
  
  <ul>
  <li>I should make it clear that this is a different image to the one that I used for the above MD5 checksums. I didn't think to use the same image.</li>
  </ul>
  
  <p>UPDATE: Using the two images I linked above, I found the differences between the two files. There are two sequences of 32 bytes that are different in one image from the other. The files are otherwise identical.</p>
  
  <pre><code>n.b. the first character is numbered as character 1, not character 0
  
  n.b. 2116624 and 2493456 are both 16 modulo 32.
       The difference between them is 368 * 1024.
  
  character 2116624 through line 2116655 (32 characters):
  
      original image:
  
      3c bc 20 19 eb 93 cd 34 db 93 68 7c 8d 5e 37 d4
      d3 84 91 70 7e 7c 82 3e e9 e8 3d eb 2e ff 00 ce
  
      bad image:
  
      89 c9 54 a6 e5 3d f4 fc 8e 7f 68 d5 47 14 41 f6
      55 11 7d a6 55 24 a8 e0 f7 a8 a4 43 06 18 c2 c1
  
  character 2493456 through character 2493487 (32 characters):
  
      original image:
  
      3d a4 61 37 19 75 63 2e 51 62 ca 07 e0 9e 49 35
      5d 65 8d 22 01 7f 5e b4 a7 19 3a 7a ef 72 1c e3
  
      bad image:
  
      4f 99 26 39 6a db d9 cd 3e 5b ec 63 46 3c b4 ef
      2d b6 30 35 0f 12 a1 b6 9a 11 68 1a 69 07 0c 49
  </code></pre>