php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #60232 Wrong lock support detection for streams
Submitted: 2011-11-07 12:04 UTC Modified: 2012-02-09 10:14 UTC
Votes:2
Avg. Score:4.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: goetas at lignano dot it Assigned:
Status: Not a bug Package: Streams related
PHP Version: 5.3.8 OS: ubuntu
Private report: No CVE-ID: None
 [2011-11-07 12:04 UTC] goetas at lignano dot it
Description:
------------
I have implemented my own stream that support locking (defined the function stream_lock). 
when use: 
file_put_contents("sqlfile://www.pppoa.it/x", "", LOCK_EX);

I get this error: Exclusive locks may only be set for regular files

I've take a look into PHP_5_3/ext/standard/file.c,  and at line 620 there is a check, that generates this error.

Few lines after, at line 635 there is a second check, for stream lock support.
But these lines of code (635...) is newer reachable because all operations on stream that require locking will stop on line 623.





Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-11-16 12:32 UTC] felipe@php.net
The first check was introduced to fix the issue reported in bug #44501.
 [2011-11-16 19:26 UTC] goetas at lignano dot it
in file.c there is a double check for stream locking support, but the first check is done in the worong way. 
i'm not a c programmer, i think that should be done somethink like this

if(file_lock) then
   if(is_stream && !stream_support_locking) then
     throw error
   endif
endif
 [2011-11-29 13:30 UTC] iliaa@php.net
-Status: Open +Status: Bogus
 [2011-11-29 13:30 UTC] iliaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

The stream_support_locking() merely checks if stream->fd is present, it does not 
"actually" check if locking is supported. Therefor the check is actually correct.
 [2011-11-29 15:15 UTC] goetas at lignano dot it
This is extracted from standard/file.c starting from line 618.

I have commented some fundamental parts for this bug.

...
} else if (flags & LOCK_EX) { // exclusive lock?
  // the following lines does not check any real stream locking support
  // this code will block all protocols 
  // that use LOCK_EX, except file://


  // are we using a stream protocol? eg: file:// http:// custom://
  if (php_memnstr(filename, "://", sizeof("://") - 1, filename + filename_len)) {


    // if the protocol is not  file:// throw an error
    if (strncasecmp(filename, "file://", sizeof("file://") - 1)) { 
      php_error_docref(NULL TSRMLS_CC, E_WARNING, 
          "Exclusive locks may only be set for regular files");
      RETURN_FALSE;
    }

  }
  mode[0] = 'c';
}

// the following lines can not be reached by any other 
//protocol using LOCK_EX, except file://
mode[2] = '\0';

stream = php_stream_open_wrapper_ex(filename, mode, ((flags & PHP_FILE_USE_INCLUDE_PATH) ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
if (stream == NULL) {
  RETURN_FALSE;
}

// better locking check
if (flags & LOCK_EX && (!php_stream_supports_lock(stream) || php_stream_lock(stream, LOCK_EX))) { 
  php_stream_close(stream);
  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Exclusive locks are not supported for this stream");
  RETURN_FALSE;
}

  

According to current implementation of file_put_contents there is no way to use exclusive locks support with a custom protocol wrapper.
 [2012-02-09 09:25 UTC] karsten at typo3 dot org
I have just been bitten by this issue, and for all I can tell the reasoning 
behind what goetas writes makes me think "yeah, right!".

Could someone *please* reevaluate the "not a bug" statements?
 [2012-02-09 10:14 UTC] goetas at lignano dot it
+1!
i'm right with you!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 05:01:30 2024 UTC