From: Arnaud Le Blanc Date: Wed, 26 Nov 2008 04:20:41 +0000 (+0000) Subject: MFH: Fixed bug #46673 (stream_lock call with wrong paramater) X-Git-Tag: php-5.2.7RC5~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9ed3965300491602a8f4ed56528657927304d772;p=php MFH: Fixed bug #46673 (stream_lock call with wrong paramater) --- diff --git a/NEWS b/NEWS index e397ce49fb..753736b55f 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ PHP NEWS - Upgraded PCRE to version 7.8 (Ilia) - Fixed memory leak inside readline_callback_handler_remove() function. (Felipe) +- Fixed bug #46673 (stream_lock call with wrong paramater). (Arnaud) - Fixed bug #46649 (Setting array element with that same array produces inconsistent results). (Arnaud) - Fixed bug #46626 (mb_convert_case does not handle apostrophe correctly). diff --git a/ext/standard/file.c b/ext/standard/file.c index 52e5ece24a..f90fc4df25 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -195,10 +195,10 @@ PHP_MINIT_FUNCTION(file) REGISTER_LONG_CONSTANT("SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LOCK_SH", 1, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LOCK_EX", 2, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LOCK_UN", 3, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LOCK_NB", 4, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOCK_SH", PHP_LOCK_SH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOCK_EX", PHP_LOCK_EX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOCK_UN", PHP_LOCK_UN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOCK_NB", PHP_LOCK_NB, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_NOTIFY_CONNECT", PHP_STREAM_NOTIFY_CONNECT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_REQUIRED", PHP_STREAM_NOTIFY_AUTH_REQUIRED, CONST_CS | CONST_PERSISTENT); @@ -347,7 +347,7 @@ PHP_FUNCTION(flock) } /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */ - act = flock_values[act - 1] | (operation & 4 ? LOCK_NB : 0); + act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0); if (php_stream_lock(stream, act)) { if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) { Z_LVAL_P(arg3) = 1; diff --git a/ext/standard/flock_compat.h b/ext/standard/flock_compat.h index 3e0fcd7c33..cd13f93bda 100644 --- a/ext/standard/flock_compat.h +++ b/ext/standard/flock_compat.h @@ -35,6 +35,12 @@ PHPAPI int php_flock(int fd, int operation); PHPAPI int flock(int fd, int operation); #endif +/* Userland LOCK_* constants */ +#define PHP_LOCK_SH 1 +#define PHP_LOCK_EX 2 +#define PHP_LOCK_UN 3 +#define PHP_LOCK_NB 4 + #ifdef PHP_WIN32 #define EWOULDBLOCK WSAEWOULDBLOCK # define fsync _commit diff --git a/ext/standard/tests/file/userstreams_004.phpt b/ext/standard/tests/file/userstreams_004.phpt new file mode 100644 index 0000000000..da9f148b5d --- /dev/null +++ b/ext/standard/tests/file/userstreams_004.phpt @@ -0,0 +1,58 @@ +--TEST-- +User-space streams: stream_lock() +--FILE-- +mode = $mode; + } +} +function test($name, $fd, $mode) { + echo "------ $name: -------\n"; + flock($fd, $mode); + $data = stream_get_meta_data($fd); + var_dump($data['wrapper_data']->mode === $mode); +} + +var_dump(stream_wrapper_register('test', 'test_wrapper')); +var_dump(stream_wrapper_register('test2', 'test_wrapper_base')); + +$fd = fopen("test://foo","r"); +$fd2 = fopen("test2://foo","r"); + +test("stream_lock not implemented", $fd2, LOCK_EX); + +foreach(array("LOCK_SH","LOCK_EX","LOCK_UN") as $mode) { + test("fclock($mode)", $fd, constant($mode)); + test("fclock($mode|LOCK_NB)", $fd, constant($mode)|LOCK_NB); +} + +?> +--EXPECTF-- +bool(true) +bool(true) +------ stream_lock not implemented: ------- + +Warning: flock(): test_wrapper_base::stream_lock is not implemented! in %s +bool(false) +------ fclock(LOCK_SH): ------- +bool(true) +------ fclock(LOCK_SH|LOCK_NB): ------- +bool(true) +------ fclock(LOCK_EX): ------- +bool(true) +------ fclock(LOCK_EX|LOCK_NB): ------- +bool(true) +------ fclock(LOCK_UN): ------- +bool(true) +------ fclock(LOCK_UN|LOCK_NB): ------- +bool(true) diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 85663d9d34..1cc064cb71 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -22,6 +22,10 @@ #include "php.h" #include "php_globals.h" #include "ext/standard/file.h" +#include "ext/standard/flock_compat.h" +#ifdef HAVE_SYS_FILE_H +#include +#endif static int le_protocols; @@ -908,7 +912,23 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value case PHP_STREAM_OPTION_LOCKING: MAKE_STD_ZVAL(zvalue); - ZVAL_LONG(zvalue, value); + ZVAL_LONG(zvalue, 0); + + if (value & LOCK_NB) { + Z_LVAL_P(zvalue) |= PHP_LOCK_NB; + } + switch(value & ~LOCK_NB) { + case LOCK_SH: + Z_LVAL_P(zvalue) |= PHP_LOCK_SH; + break; + case LOCK_EX: + Z_LVAL_P(zvalue) |= PHP_LOCK_EX; + break; + case LOCK_UN: + Z_LVAL_P(zvalue) |= PHP_LOCK_UN; + break; + } + args[0] = &zvalue; /* TODO wouldblock */