mirror of
https://github.com/php/php-src.git
synced 2026-04-03 14:12:38 +02:00
Merge branch 'PHP-7.0' of git.php.net:/php-src into PHP-7.0
* 'PHP-7.0' of git.php.net:/php-src: Remove __halt_compiler from semi-reserved tokens Fixed Bug #71974 Trans sid will always be send, even if cookies are available Optimized array_fill(). This is a perfect function for fast creation of packed arrays. Fixed build fix merge mistake fix tests PostgreSQL's PDOStatement::getColumnMeta() fills in table's name. fix indent Fixed bug #71978 (Existence of return type hint affects other compatibility rules) fix test fix bug #71667 (emulate how mssql extension names "computed" columns) update NEWS add 32-bit specific variont for #62498 skip test on 32-bit make opcache lockfile path configurable return zvals instead of strings, cast or not based on stringify attribute fix test add skip slow test
This commit is contained in:
@@ -80,7 +80,6 @@ class Obj
|
||||
function __FILE__(){ echo __METHOD__, PHP_EOL; }
|
||||
function __DIR__(){ echo __METHOD__, PHP_EOL; }
|
||||
function __NAMESPACE__(){ echo __METHOD__, PHP_EOL; }
|
||||
function __halt_compiler(){ echo __METHOD__, PHP_EOL; }
|
||||
}
|
||||
|
||||
$obj = new Obj;
|
||||
@@ -160,7 +159,6 @@ $obj->__LINE__();
|
||||
$obj->__FILE__();
|
||||
$obj->__DIR__();
|
||||
$obj->__NAMESPACE__();
|
||||
$obj->__halt_compiler();
|
||||
|
||||
echo "\nDone\n";
|
||||
|
||||
@@ -240,6 +238,5 @@ Obj::__LINE__
|
||||
Obj::__FILE__
|
||||
Obj::__DIR__
|
||||
Obj::__NAMESPACE__
|
||||
Obj::__halt_compiler
|
||||
|
||||
Done
|
||||
|
||||
@@ -80,7 +80,6 @@ class Obj
|
||||
static function __FILE__(){ echo __METHOD__, PHP_EOL; }
|
||||
static function __DIR__(){ echo __METHOD__, PHP_EOL; }
|
||||
static function __NAMESPACE__(){ echo __METHOD__, PHP_EOL; }
|
||||
static function __halt_compiler(){ echo __METHOD__, PHP_EOL; }
|
||||
}
|
||||
|
||||
Obj::empty();
|
||||
@@ -158,7 +157,6 @@ Obj::__LINE__();
|
||||
Obj::__FILE__();
|
||||
Obj::__DIR__();
|
||||
Obj::__NAMESPACE__();
|
||||
Obj::__halt_compiler();
|
||||
|
||||
echo "\nDone\n";
|
||||
|
||||
@@ -238,6 +236,5 @@ Obj::__LINE__
|
||||
Obj::__FILE__
|
||||
Obj::__DIR__
|
||||
Obj::__NAMESPACE__
|
||||
Obj::__halt_compiler
|
||||
|
||||
Done
|
||||
|
||||
@@ -79,7 +79,6 @@ class Obj
|
||||
const __FILE__ = '__FILE__';
|
||||
const __DIR__ = '__DIR__';
|
||||
const __NAMESPACE__ = '__NAMESPACE__';
|
||||
const __HALT_COMPILER = '__halt_compiler';
|
||||
}
|
||||
|
||||
echo Obj::EMPTY, PHP_EOL;
|
||||
@@ -156,7 +155,6 @@ echo Obj::__LINE__, PHP_EOL;
|
||||
echo Obj::__FILE__, PHP_EOL;
|
||||
echo Obj::__DIR__, PHP_EOL;
|
||||
echo Obj::__NAMESPACE__, PHP_EOL;
|
||||
echo Obj::__HALT_COMPILER, PHP_EOL;
|
||||
|
||||
echo "\nDone\n";
|
||||
|
||||
@@ -235,6 +233,5 @@ __LINE__
|
||||
__FILE__
|
||||
__DIR__
|
||||
__NAMESPACE__
|
||||
__halt_compiler
|
||||
|
||||
Done
|
||||
|
||||
21
Zend/tests/return_types/bug71978.phpt
Normal file
21
Zend/tests/return_types/bug71978.phpt
Normal file
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Bug #71978 (Existence of return type hint affects other compatibility rules)
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
function foo(int $a) {}
|
||||
}
|
||||
class B extends A {
|
||||
function foo(string $a) {}
|
||||
}
|
||||
class A1 {
|
||||
function foo(int $a): int {}
|
||||
}
|
||||
class B1 extends A1 {
|
||||
function foo(string $a): int {}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Declaration of B::foo(string $a) should be compatible with A::foo(int $a) in %s on line %d
|
||||
|
||||
Warning: Declaration of B1::foo(string $a): int should be compatible with A1::foo(int $a): int in %s on line %d
|
||||
@@ -243,11 +243,6 @@ static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_inf
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (proto_arg_info->type_hint && proto_arg_info->allow_null && !fe_arg_info->allow_null) {
|
||||
/* incompatible nullability */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -324,6 +319,11 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (proto_arg_info->type_hint && proto_arg_info->allow_null && !fe_arg_info->allow_null) {
|
||||
/* incompatible nullability */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* by-ref constraints on arguments are invariant */
|
||||
if (fe_arg_info->pass_by_reference != proto_arg_info->pass_by_reference) {
|
||||
return 0;
|
||||
@@ -570,17 +570,31 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
|
||||
}
|
||||
|
||||
if (child->common.prototype && (
|
||||
child->common.prototype->common.fn_flags & (ZEND_ACC_ABSTRACT | ZEND_ACC_HAS_RETURN_TYPE)
|
||||
child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT
|
||||
)) {
|
||||
if (UNEXPECTED(!zend_do_perform_implementation_check(child, child->common.prototype))) {
|
||||
zend_string *method_prototype = zend_get_function_declaration(child->common.prototype);
|
||||
zend_string *child_prototype = zend_get_function_declaration(child);
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", ZSTR_VAL(child_prototype), ZSTR_VAL(method_prototype));
|
||||
}
|
||||
} else if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) {
|
||||
parent = child->common.prototype;
|
||||
}
|
||||
if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) {
|
||||
int error_level;
|
||||
const char *error_verb;
|
||||
zend_string *method_prototype = zend_get_function_declaration(parent);
|
||||
zend_string *child_prototype = zend_get_function_declaration(child);
|
||||
zend_error(E_WARNING, "Declaration of %s should be compatible with %s", ZSTR_VAL(child_prototype), ZSTR_VAL(method_prototype));
|
||||
|
||||
if (child->common.prototype && (
|
||||
child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT
|
||||
)) {
|
||||
error_level = E_COMPILE_ERROR;
|
||||
error_verb = "must";
|
||||
} else if ((parent->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) &&
|
||||
(!(child->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
!zend_do_perform_type_hint_check(child, child->common.arg_info - 1, parent, parent->common.arg_info - 1))) {
|
||||
error_level = E_COMPILE_ERROR;
|
||||
error_verb = "must";
|
||||
} else {
|
||||
error_level = E_WARNING;
|
||||
error_verb = "should";
|
||||
}
|
||||
zend_error(error_level, "Declaration of %s %s be compatible with %s", ZSTR_VAL(child_prototype), error_verb, ZSTR_VAL(method_prototype));
|
||||
zend_string_free(child_prototype);
|
||||
zend_string_free(method_prototype);
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ reserved_non_modifiers:
|
||||
| T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
|
||||
| T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK
|
||||
| T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
|
||||
| T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER
|
||||
| T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C
|
||||
;
|
||||
|
||||
semi_reserved:
|
||||
|
||||
@@ -213,3 +213,6 @@ opcache.mmap_base
|
||||
processes have to map shared memory into the same address space. This
|
||||
directive allows to manually fix the "Unable to reattach to base address"
|
||||
errors.
|
||||
|
||||
opcache.lockfile_path (default "/tmp")
|
||||
Absolute path used to store shared lockfiles.
|
||||
|
||||
@@ -217,6 +217,7 @@ typedef struct _zend_accel_directives {
|
||||
zend_long max_file_size;
|
||||
zend_long interned_strings_buffer;
|
||||
char *restrict_api;
|
||||
char *lockfile_path;
|
||||
#ifdef HAVE_OPCACHE_FILE_CACHE
|
||||
char *file_cache;
|
||||
zend_bool file_cache_only;
|
||||
|
||||
@@ -298,6 +298,7 @@ ZEND_INI_BEGIN()
|
||||
STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals)
|
||||
STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals)
|
||||
STD_PHP_INI_ENTRY("opcache.restrict_api" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.restrict_api, zend_accel_globals, accel_globals)
|
||||
STD_PHP_INI_ENTRY("opcache.lockfile_path" , "/tmp" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.lockfile_path, zend_accel_globals, accel_globals)
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
STD_PHP_INI_ENTRY("opcache.mmap_base", NULL, PHP_INI_SYSTEM, OnUpdateString, accel_directives.mmap_base, zend_accel_globals, accel_globals)
|
||||
@@ -710,6 +711,7 @@ static ZEND_FUNCTION(opcache_get_configuration)
|
||||
add_assoc_bool(&directives, "opcache.fast_shutdown", ZCG(accel_directives).fast_shutdown);
|
||||
add_assoc_bool(&directives, "opcache.enable_file_override", ZCG(accel_directives).file_override_enabled);
|
||||
add_assoc_long(&directives, "opcache.optimization_level", ZCG(accel_directives).optimization_level);
|
||||
add_assoc_string(&directives, "opcache.lockfile_path", STRING_NOT_NULL(ZCG(accel_directives).lockfile_path));
|
||||
|
||||
#ifdef HAVE_OPCACHE_FILE_CACHE
|
||||
add_assoc_string(&directives, "opcache.file_cache", ZCG(accel_directives).file_cache ? ZCG(accel_directives).file_cache : "");
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
# include "sys/mman.h"
|
||||
#endif
|
||||
|
||||
#define TMP_DIR "/tmp"
|
||||
#define SEM_FILENAME_PREFIX ".ZendSem."
|
||||
#define S_H(s) g_shared_alloc_handler->s
|
||||
|
||||
@@ -55,7 +54,7 @@ zend_smm_shared_globals *smm_shared_globals;
|
||||
static MUTEX_T zts_lock;
|
||||
#endif
|
||||
int lock_file;
|
||||
static char lockfile_name[sizeof(TMP_DIR) + sizeof(SEM_FILENAME_PREFIX) + 8];
|
||||
static char lockfile_name[MAXPATHLEN];
|
||||
#endif
|
||||
|
||||
static const zend_shared_memory_handler_entry handler_table[] = {
|
||||
@@ -75,7 +74,7 @@ static const zend_shared_memory_handler_entry handler_table[] = {
|
||||
};
|
||||
|
||||
#ifndef ZEND_WIN32
|
||||
void zend_shared_alloc_create_lock(void)
|
||||
void zend_shared_alloc_create_lock(char *lockfile_path)
|
||||
{
|
||||
int val;
|
||||
|
||||
@@ -83,7 +82,7 @@ void zend_shared_alloc_create_lock(void)
|
||||
zts_lock = tsrm_mutex_alloc();
|
||||
#endif
|
||||
|
||||
sprintf(lockfile_name, "%s/%sXXXXXX", TMP_DIR, SEM_FILENAME_PREFIX);
|
||||
snprintf(lockfile_name, sizeof(lockfile_name), "%s/%sXXXXXX", lockfile_path, SEM_FILENAME_PREFIX);
|
||||
lock_file = mkstemp(lockfile_name);
|
||||
fchmod(lock_file, 0666);
|
||||
|
||||
@@ -163,7 +162,11 @@ int zend_shared_alloc_startup(size_t requested_size)
|
||||
smm_shared_globals = &tmp_shared_globals;
|
||||
ZSMMG(shared_free) = requested_size; /* goes to tmp_shared_globals.shared_free */
|
||||
|
||||
#ifndef ZEND_WIN32
|
||||
zend_shared_alloc_create_lock(ZCG(accel_directives).lockfile_path);
|
||||
#else
|
||||
zend_shared_alloc_create_lock();
|
||||
#endif
|
||||
|
||||
if (ZCG(accel_directives).memory_model && ZCG(accel_directives).memory_model[0]) {
|
||||
char *model = ZCG(accel_directives).memory_model;
|
||||
|
||||
@@ -101,6 +101,7 @@ static int dblib_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len
|
||||
stmt->driver_data = S;
|
||||
stmt->methods = &dblib_stmt_methods;
|
||||
stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
|
||||
S->computed_column_name_count = 0;
|
||||
S->err.sqlstate = stmt->error_code;
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -218,21 +218,31 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (colno == 0) {
|
||||
S->computed_column_name_count = 0;
|
||||
}
|
||||
|
||||
col = &stmt->columns[colno];
|
||||
fname = (char*)dbcolname(H->link, colno+1);
|
||||
|
||||
if (fname && *fname) {
|
||||
col->name = zend_string_init(fname, strlen(fname), 0);
|
||||
} else {
|
||||
char buf[16];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "computed%d", colno);
|
||||
col->name = zend_string_init(buf, len, 0);
|
||||
if (S->computed_column_name_count > 0) {
|
||||
char buf[16];
|
||||
int len;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "computed%d", S->computed_column_name_count);
|
||||
col->name = zend_string_init(buf, len, 0);
|
||||
} else {
|
||||
col->name = zend_string_init("computed", strlen("computed"), 0);
|
||||
}
|
||||
|
||||
S->computed_column_name_count++;
|
||||
}
|
||||
|
||||
col->maxlen = dbcollen(H->link, colno+1);
|
||||
col->param_type = PDO_PARAM_STR;
|
||||
col->param_type = PDO_PARAM_ZVAL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -245,78 +255,161 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
|
||||
pdo_dblib_db_handle *H = S->H;
|
||||
|
||||
int coltype;
|
||||
unsigned int tmp_len;
|
||||
char *tmp_ptr = NULL;
|
||||
char *data, *tmp_data;
|
||||
unsigned int data_len, tmp_data_len;
|
||||
zval *zv = NULL;
|
||||
|
||||
coltype = dbcoltype(H->link, colno+1);
|
||||
data = dbdata(H->link, colno+1);
|
||||
data_len = dbdatlen(H->link, colno+1);
|
||||
|
||||
*len = dbdatlen(H->link, colno+1);
|
||||
*ptr = dbdata(H->link, colno+1);
|
||||
if (data_len != 0 || data != NULL) {
|
||||
if (stmt->dbh->stringify) {
|
||||
switch (coltype) {
|
||||
case SQLFLT4:
|
||||
case SQLFLT8:
|
||||
case SQLINT4:
|
||||
case SQLINT2:
|
||||
case SQLINT1:
|
||||
case SQLBIT: {
|
||||
if (dbwillconvert(coltype, SQLCHAR)) {
|
||||
tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
|
||||
tmp_data = emalloc(tmp_data_len);
|
||||
data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, tmp_data, -1);
|
||||
|
||||
if (*len == 0 && *ptr == NULL) {
|
||||
return 1;
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRING(zv, tmp_data);
|
||||
|
||||
efree(tmp_data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!zv) {
|
||||
switch (coltype) {
|
||||
case SQLCHAR:
|
||||
case SQLVARCHAR:
|
||||
case SQLTEXT: {
|
||||
#if ilia_0
|
||||
while (data_len>0 && data[data_len-1] == ' ') { /* nuke trailing whitespace */
|
||||
data_len--;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
case SQLVARBINARY:
|
||||
case SQLBINARY:
|
||||
case SQLIMAGE: {
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRINGL(zv, data, data_len);
|
||||
|
||||
break;
|
||||
}
|
||||
case SQLDATETIME:
|
||||
case SQLDATETIM4: {
|
||||
int dl;
|
||||
DBDATEREC di;
|
||||
DBDATEREC dt;
|
||||
|
||||
dbconvert(H->link, coltype, data, -1, SQLDATETIME, (LPBYTE) &dt, -1);
|
||||
dbdatecrack(H->link, &di, (DBDATETIME *) &dt);
|
||||
|
||||
dl = spprintf(&tmp_data, 20, "%d-%02d-%02d %02d:%02d:%02d",
|
||||
#if defined(PHP_DBLIB_IS_MSSQL) || defined(MSDBLIB)
|
||||
di.year, di.month, di.day, di.hour, di.minute, di.second
|
||||
#else
|
||||
di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond
|
||||
#endif
|
||||
);
|
||||
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRINGL(zv, tmp_data, dl);
|
||||
|
||||
efree(tmp_data);
|
||||
|
||||
break;
|
||||
}
|
||||
case SQLFLT4: {
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_DOUBLE(zv, (double) (*(DBFLT4 *) data));
|
||||
|
||||
break;
|
||||
}
|
||||
case SQLFLT8: {
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_DOUBLE(zv, (double) (*(DBFLT8 *) data));
|
||||
|
||||
break;
|
||||
}
|
||||
case SQLINT4: {
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_LONG(zv, (long) ((int) *(DBINT *) data));
|
||||
|
||||
break;
|
||||
}
|
||||
case SQLINT2: {
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_LONG(zv, (long) ((int) *(DBSMALLINT *) data));
|
||||
|
||||
break;
|
||||
}
|
||||
case SQLINT1:
|
||||
case SQLBIT: {
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_LONG(zv, (long) ((int) *(DBTINYINT *) data));
|
||||
|
||||
break;
|
||||
}
|
||||
case SQLMONEY:
|
||||
case SQLMONEY4:
|
||||
case SQLMONEYN: {
|
||||
DBFLT8 money_value;
|
||||
dbconvert(NULL, coltype, data, 8, SQLFLT8, (LPBYTE)&money_value, -1);
|
||||
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_DOUBLE(zv, money_value);
|
||||
|
||||
if (stmt->dbh->stringify) {
|
||||
convert_to_string(zv);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#ifdef SQLUNIQUE
|
||||
case SQLUNIQUE: {
|
||||
#else
|
||||
case 36: { /* FreeTDS hack */
|
||||
#endif
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRINGL(zv, data, 16); /* uniqueidentifier is a 16-byte binary number */
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (dbwillconvert(coltype, SQLCHAR)) {
|
||||
tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
|
||||
tmp_data = emalloc(tmp_data_len);
|
||||
data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, tmp_data, -1);
|
||||
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRING(zv, tmp_data);
|
||||
|
||||
efree(tmp_data);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (coltype) {
|
||||
case SQLVARBINARY:
|
||||
case SQLBINARY:
|
||||
case SQLIMAGE:
|
||||
case SQLTEXT:
|
||||
/* FIXME: Above types should be returned as a stream as they can be VERY large */
|
||||
case SQLCHAR:
|
||||
case SQLVARCHAR:
|
||||
tmp_ptr = emalloc(*len + 1);
|
||||
memcpy(tmp_ptr, *ptr, *len);
|
||||
tmp_ptr[*len] = '\0';
|
||||
*ptr = tmp_ptr;
|
||||
break;
|
||||
case SQLMONEY:
|
||||
case SQLMONEY4:
|
||||
case SQLMONEYN: {
|
||||
DBFLT8 money_value;
|
||||
dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8);
|
||||
*len = spprintf(&tmp_ptr, 0, "%.4f", money_value);
|
||||
*ptr = tmp_ptr;
|
||||
break;
|
||||
}
|
||||
case SQLUNIQUE: {
|
||||
*len = 37;
|
||||
tmp_ptr = emalloc(*len + 1);
|
||||
*len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len);
|
||||
php_strtoupper(tmp_ptr, *len);
|
||||
tmp_ptr[36] = '\0';
|
||||
*ptr = tmp_ptr;
|
||||
break;
|
||||
}
|
||||
case SQLDATETIM4:
|
||||
case SQLDATETIME: {
|
||||
DBDATETIME dt;
|
||||
DBDATEREC di;
|
||||
|
||||
dbconvert(H->link, coltype, (BYTE*) *ptr, -1, SQLDATETIME, (LPBYTE) &dt, -1);
|
||||
dbdatecrack(H->link, &di, &dt);
|
||||
|
||||
*len = spprintf((char**) &tmp_ptr, 20, "%d-%02d-%02d %02d:%02d:%02d",
|
||||
#if defined(PHP_DBLIB_IS_MSSQL) || defined(MSDBLIB)
|
||||
di.year, di.month, di.day, di.hour, di.minute, di.second
|
||||
#else
|
||||
di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond
|
||||
#endif
|
||||
);
|
||||
|
||||
*ptr = (char*) tmp_ptr;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (dbwillconvert(coltype, SQLCHAR)) {
|
||||
tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */
|
||||
tmp_ptr = emalloc(tmp_len);
|
||||
*len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1);
|
||||
*ptr = tmp_ptr;
|
||||
} else {
|
||||
*len = 0; /* FIXME: Silently fails and returns null on conversion errors */
|
||||
*ptr = NULL;
|
||||
}
|
||||
if (zv != NULL) {
|
||||
*ptr = (char*)zv;
|
||||
*len = sizeof(zval);
|
||||
} else {
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
*caller_frees = 1;
|
||||
@@ -335,6 +428,7 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zva
|
||||
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
|
||||
pdo_dblib_db_handle *H = S->H;
|
||||
DBTYPEINFO* dbtypeinfo;
|
||||
int coltype;
|
||||
|
||||
if(colno >= stmt->column_count || colno < 0) {
|
||||
return FAILURE;
|
||||
@@ -346,14 +440,28 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zva
|
||||
|
||||
if(!dbtypeinfo) return FAILURE;
|
||||
|
||||
coltype = dbcoltype(H->link, colno+1);
|
||||
|
||||
add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) );
|
||||
add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision );
|
||||
add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale );
|
||||
add_assoc_string(return_value, "column_source", dbcolsource(H->link, colno+1));
|
||||
add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(dbcoltype(H->link, colno+1)));
|
||||
add_assoc_long(return_value, "native_type_id", dbcoltype(H->link, colno+1));
|
||||
add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(coltype));
|
||||
add_assoc_long(return_value, "native_type_id", coltype);
|
||||
add_assoc_long(return_value, "native_usertype_id", dbcolutype(H->link, colno+1));
|
||||
|
||||
switch (coltype) {
|
||||
case SQLBIT:
|
||||
case SQLINT1:
|
||||
case SQLINT2:
|
||||
case SQLINT4:
|
||||
add_assoc_long(return_value, "pdo_type", PDO_PARAM_INT);
|
||||
break;
|
||||
default:
|
||||
add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
pdo_dblib_db_handle *H;
|
||||
pdo_dblib_err err;
|
||||
unsigned int computed_column_name_count;
|
||||
} pdo_dblib_stmt;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -37,21 +37,21 @@ array(4) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["val"]=>
|
||||
string(1) "1"
|
||||
int(1)
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["val"]=>
|
||||
string(1) "2"
|
||||
int(2)
|
||||
}
|
||||
[2]=>
|
||||
array(1) {
|
||||
["val"]=>
|
||||
string(1) "3"
|
||||
int(3)
|
||||
}
|
||||
[3]=>
|
||||
array(1) {
|
||||
["val"]=>
|
||||
string(1) "4"
|
||||
int(4)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ $stmt->execute();
|
||||
var_dump($stmt->getColumnMeta(0));
|
||||
$stmt = null;
|
||||
?>
|
||||
--EXPECT--
|
||||
array(8) {
|
||||
--EXPECTF--
|
||||
array(10) {
|
||||
["max_length"]=>
|
||||
int(255)
|
||||
["precision"]=>
|
||||
@@ -26,10 +26,14 @@ array(8) {
|
||||
string(13) "TABLE_CATALOG"
|
||||
["native_type"]=>
|
||||
string(4) "char"
|
||||
["native_type_id"]=>
|
||||
int(%d)
|
||||
["native_usertype_id"]=>
|
||||
int(%d)
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
["name"]=>
|
||||
string(13) "TABLE_CATALOG"
|
||||
["len"]=>
|
||||
int(255)
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
}
|
||||
|
||||
@@ -23,21 +23,21 @@ array(3) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["My Field"]=>
|
||||
string(1) "1"
|
||||
int(1)
|
||||
["Another Field"]=>
|
||||
string(11) "test_string"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
["My Field"]=>
|
||||
string(1) "2"
|
||||
int(2)
|
||||
["Another Field"]=>
|
||||
string(11) "test_string"
|
||||
}
|
||||
[2]=>
|
||||
array(2) {
|
||||
["My Field"]=>
|
||||
string(1) "3"
|
||||
int(3)
|
||||
["Another Field"]=>
|
||||
string(11) "test_string"
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[computed0] => 1
|
||||
[computed] => 1
|
||||
[0] => 1
|
||||
)
|
||||
|
||||
|
||||
34
ext/pdo_dblib/tests/bug_71667.phpt
Normal file
34
ext/pdo_dblib/tests/bug_71667.phpt
Normal file
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
PDO_DBLIB: Emulate how mssql extension names "computed" columns
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_dblib')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
|
||||
$stmt = $db->prepare("SELECT 1, 2 AS named, 3");
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(6) {
|
||||
["computed"]=>
|
||||
string(1) "1"
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
["named"]=>
|
||||
string(1) "2"
|
||||
[1]=>
|
||||
string(1) "2"
|
||||
["computed1"]=>
|
||||
string(1) "3"
|
||||
[2]=>
|
||||
string(1) "3"
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ PDO_DBLIB: Set query timeouts
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_dblib')) die('skip not loaded');
|
||||
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
?>
|
||||
--FILE--
|
||||
|
||||
66
ext/pdo_dblib/tests/types.phpt
Normal file
66
ext/pdo_dblib/tests/types.phpt
Normal file
@@ -0,0 +1,66 @@
|
||||
--TEST--
|
||||
PDO_DBLIB: Column data types, with or without stringifying
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_dblib')) die('skip not loaded');
|
||||
require __DIR__ . '/config.inc';
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
'foo' AS [char],
|
||||
CAST('2030-01-01 23:59:59' AS DATETIME) AS [datetime],
|
||||
CAST(0 AS BIT) AS [false],
|
||||
10.5 AS [float],
|
||||
1000 AS [int],
|
||||
CAST(10.5 AS MONEY) AS [money],
|
||||
CAST('1950-01-18 23:00:00' AS SMALLDATETIME) as [smalldatetime],
|
||||
CAST(1 AS BIT) AS [true]
|
||||
";
|
||||
|
||||
$stmt = $db->query($sql);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
var_dump($row['char'] === 'foo');
|
||||
var_dump($row['datetime'] === '2030-01-01 23:59:59');
|
||||
var_dump($row['false'] === 0);
|
||||
var_dump($row['float'] === 10.5);
|
||||
var_dump($row['int'] === 1000);
|
||||
var_dump($row['money'] === 10.5);
|
||||
var_dump($row['smalldatetime'] === '1950-01-18 23:00:00');
|
||||
var_dump($row['true'] === 1);
|
||||
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
$stmt = $db->query($sql);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
var_dump($row['char'] === 'foo');
|
||||
var_dump($row['datetime'] === '2030-01-01 23:59:59');
|
||||
var_dump($row['false'] === '0');
|
||||
var_dump($row['float'] === '10.5');
|
||||
var_dump($row['int'] === '1000');
|
||||
var_dump($row['money'] === '10.5');
|
||||
var_dump($row['smalldatetime'] === '1950-01-18 23:00:00');
|
||||
var_dump($row['true'] === '1');
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
@@ -587,12 +587,40 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulon
|
||||
return 1;
|
||||
}
|
||||
|
||||
static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGconn *conn)
|
||||
{
|
||||
char *table_name = NULL;
|
||||
PGresult *tmp_res;
|
||||
char *querystr = NULL;
|
||||
|
||||
spprintf(&querystr, 0, "SELECT RELNAME FROM PG_CLASS WHERE OID=%d", oid);
|
||||
|
||||
if ((tmp_res = PQexec(conn, querystr)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
|
||||
if (tmp_res) {
|
||||
PQclear(tmp_res);
|
||||
}
|
||||
efree(querystr);
|
||||
return 0;
|
||||
}
|
||||
efree(querystr);
|
||||
|
||||
if ((table_name = PQgetvalue(tmp_res, 0, 0)) == NULL) {
|
||||
PQclear(tmp_res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PQclear(tmp_res);
|
||||
return table_name;
|
||||
}
|
||||
|
||||
static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
|
||||
{
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
PGresult *res;
|
||||
char *q=NULL;
|
||||
ExecStatusType status;
|
||||
Oid table_oid;
|
||||
char *table_name=NULL;
|
||||
|
||||
if (!S->result) {
|
||||
return FAILURE;
|
||||
@@ -605,46 +633,53 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *r
|
||||
array_init(return_value);
|
||||
add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
|
||||
|
||||
switch (S->cols[colno].pgsql_type) {
|
||||
case BOOLOID:
|
||||
add_assoc_string(return_value, "native_type", BOOLLABEL);
|
||||
break;
|
||||
case BYTEAOID:
|
||||
add_assoc_string(return_value, "native_type", BYTEALABEL);
|
||||
break;
|
||||
case INT8OID:
|
||||
add_assoc_string(return_value, "native_type", INT8LABEL);
|
||||
break;
|
||||
case INT2OID:
|
||||
add_assoc_string(return_value, "native_type", INT2LABEL);
|
||||
break;
|
||||
case INT4OID:
|
||||
add_assoc_string(return_value, "native_type", INT4LABEL);
|
||||
break;
|
||||
case TEXTOID:
|
||||
add_assoc_string(return_value, "native_type", TEXTLABEL);
|
||||
break;
|
||||
case VARCHAROID:
|
||||
add_assoc_string(return_value, "native_type", VARCHARLABEL);
|
||||
break;
|
||||
case DATEOID:
|
||||
add_assoc_string(return_value, "native_type", DATELABEL);
|
||||
break;
|
||||
case TIMESTAMPOID:
|
||||
add_assoc_string(return_value, "native_type", TIMESTAMPLABEL);
|
||||
break;
|
||||
default:
|
||||
/* Fetch metadata from Postgres system catalogue */
|
||||
spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type);
|
||||
res = PQexec(S->H->server, q);
|
||||
efree(q);
|
||||
status = PQresultStatus(res);
|
||||
if (status == PGRES_TUPLES_OK && 1 == PQntuples(res)) {
|
||||
add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0));
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
return 1;
|
||||
table_oid = PQftable(S->result, colno);
|
||||
add_assoc_long(return_value, "pgsql:table_oid", table_oid);
|
||||
table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H->server);
|
||||
if (table_name) {
|
||||
add_assoc_string(return_value, "table", table_name);
|
||||
}
|
||||
|
||||
switch (S->cols[colno].pgsql_type) {
|
||||
case BOOLOID:
|
||||
add_assoc_string(return_value, "native_type", BOOLLABEL);
|
||||
break;
|
||||
case BYTEAOID:
|
||||
add_assoc_string(return_value, "native_type", BYTEALABEL);
|
||||
break;
|
||||
case INT8OID:
|
||||
add_assoc_string(return_value, "native_type", INT8LABEL);
|
||||
break;
|
||||
case INT2OID:
|
||||
add_assoc_string(return_value, "native_type", INT2LABEL);
|
||||
break;
|
||||
case INT4OID:
|
||||
add_assoc_string(return_value, "native_type", INT4LABEL);
|
||||
break;
|
||||
case TEXTOID:
|
||||
add_assoc_string(return_value, "native_type", TEXTLABEL);
|
||||
break;
|
||||
case VARCHAROID:
|
||||
add_assoc_string(return_value, "native_type", VARCHARLABEL);
|
||||
break;
|
||||
case DATEOID:
|
||||
add_assoc_string(return_value, "native_type", DATELABEL);
|
||||
break;
|
||||
case TIMESTAMPOID:
|
||||
add_assoc_string(return_value, "native_type", TIMESTAMPLABEL);
|
||||
break;
|
||||
default:
|
||||
/* Fetch metadata from Postgres system catalogue */
|
||||
spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type);
|
||||
res = PQexec(S->H->server, q);
|
||||
efree(q);
|
||||
status = PQresultStatus(res);
|
||||
if (status == PGRES_TUPLES_OK && 1 == PQntuples(res)) {
|
||||
add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0));
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pdo_pgsql_stmt_cursor_closer(pdo_stmt_t *stmt)
|
||||
|
||||
221
ext/pdo_pgsql/tests/bug62498-32bit.phpt
Normal file
221
ext/pdo_pgsql/tests/bug62498-32bit.phpt
Normal file
@@ -0,0 +1,221 @@
|
||||
--TEST--
|
||||
PDO PgSQL Bug #62498 (pdo_pgsql inefficient when getColumnMeta() is used), 32-bit
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
if (PHP_INT_SIZE > 4) die("skip relevant for 32-bit only");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
echo "Begin test...\n";
|
||||
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$db->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
// create the table
|
||||
$db->exec("CREATE TEMPORARY TABLE bugtest_62498 (int2col INT2, int4col INT4, int8col INT8, stringcol VARCHAR(255), boolcol BOOLEAN, datecol DATE, textcol TEXT, tscol TIMESTAMP, byteacol BYTEA)");
|
||||
|
||||
// insert some data
|
||||
$statement = $db->prepare("INSERT INTO bugtest_62498 (int2col, int4col, int8col, stringcol, boolcol, datecol, textcol, tscol, byteacol) VALUES (:int2val, :int4val, :int8val, :stringval, :boolval, :dateval, :textval, :tsval, :byteaval)");
|
||||
$vals = array(
|
||||
"int2val" => "42",
|
||||
"int4val" => "42",
|
||||
"int8val" => "42",
|
||||
"stringval" => "The Answer",
|
||||
"boolval" => true,
|
||||
"dateval" => '2015-12-14',
|
||||
"textval" => "some text",
|
||||
"tsval" => 19990108,
|
||||
"byteaval" => 0,
|
||||
);
|
||||
$statement->execute($vals);
|
||||
|
||||
$select = $db->query('SELECT int2col, int4col, int8col, stringcol, boolcol, datecol, textcol, tscol, byteacol FROM bugtest_62498');
|
||||
$meta = [];
|
||||
for ($i=0; $i < count($vals); $i++) {
|
||||
$meta[] = $select->getColumnMeta($i);
|
||||
}
|
||||
var_dump($meta);
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
Begin test...
|
||||
array(9) {
|
||||
[0]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(21)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "int2"
|
||||
["name"]=>
|
||||
string(7) "int2col"
|
||||
["len"]=>
|
||||
int(2)
|
||||
["precision"]=>
|
||||
int(-1)
|
||||
["pdo_type"]=>
|
||||
int(1)
|
||||
}
|
||||
[1]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(23)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "int4"
|
||||
["name"]=>
|
||||
string(7) "int4col"
|
||||
["len"]=>
|
||||
int(4)
|
||||
["precision"]=>
|
||||
int(-1)
|
||||
["pdo_type"]=>
|
||||
int(1)
|
||||
}
|
||||
[2]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(20)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "int8"
|
||||
["name"]=>
|
||||
string(7) "int8col"
|
||||
["len"]=>
|
||||
int(8)
|
||||
["precision"]=>
|
||||
int(-1)
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
}
|
||||
[3]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(1043)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(7) "varchar"
|
||||
["name"]=>
|
||||
string(9) "stringcol"
|
||||
["len"]=>
|
||||
int(-1)
|
||||
["precision"]=>
|
||||
int(259)
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
}
|
||||
[4]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(16)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "bool"
|
||||
["name"]=>
|
||||
string(7) "boolcol"
|
||||
["len"]=>
|
||||
int(1)
|
||||
["precision"]=>
|
||||
int(-1)
|
||||
["pdo_type"]=>
|
||||
int(5)
|
||||
}
|
||||
[5]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(1082)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "date"
|
||||
["name"]=>
|
||||
string(7) "datecol"
|
||||
["len"]=>
|
||||
int(4)
|
||||
["precision"]=>
|
||||
int(-1)
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
}
|
||||
[6]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(25)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "text"
|
||||
["name"]=>
|
||||
string(7) "textcol"
|
||||
["len"]=>
|
||||
int(-1)
|
||||
["precision"]=>
|
||||
int(-1)
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
}
|
||||
[7]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(1114)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(9) "timestamp"
|
||||
["name"]=>
|
||||
string(5) "tscol"
|
||||
["len"]=>
|
||||
int(8)
|
||||
["precision"]=>
|
||||
int(-1)
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
}
|
||||
[8]=>
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(17)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(5) "bytea"
|
||||
["name"]=>
|
||||
string(8) "byteacol"
|
||||
["len"]=>
|
||||
int(-1)
|
||||
["precision"]=>
|
||||
int(-1)
|
||||
["pdo_type"]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
Done
|
||||
@@ -1,11 +1,12 @@
|
||||
--TEST--
|
||||
PDO PgSQL Bug #62498 (pdo_pgsql inefficient when getColumnMeta() is used)
|
||||
PDO PgSQL Bug #62498 (pdo_pgsql inefficient when getColumnMeta() is used), 64-bit
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
if (PHP_INT_SIZE < 8) die("skip valid for 64-bit only");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
@@ -42,13 +43,17 @@ var_dump($meta);
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
Begin test...
|
||||
array(9) {
|
||||
[0]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(21)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "int2"
|
||||
["name"]=>
|
||||
@@ -61,9 +66,13 @@ array(9) {
|
||||
int(1)
|
||||
}
|
||||
[1]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(23)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "int4"
|
||||
["name"]=>
|
||||
@@ -76,9 +85,13 @@ array(9) {
|
||||
int(1)
|
||||
}
|
||||
[2]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(20)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "int8"
|
||||
["name"]=>
|
||||
@@ -91,9 +104,13 @@ array(9) {
|
||||
int(1)
|
||||
}
|
||||
[3]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(1043)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(7) "varchar"
|
||||
["name"]=>
|
||||
@@ -106,9 +123,13 @@ array(9) {
|
||||
int(2)
|
||||
}
|
||||
[4]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(16)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "bool"
|
||||
["name"]=>
|
||||
@@ -121,9 +142,13 @@ array(9) {
|
||||
int(5)
|
||||
}
|
||||
[5]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(1082)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "date"
|
||||
["name"]=>
|
||||
@@ -136,9 +161,13 @@ array(9) {
|
||||
int(2)
|
||||
}
|
||||
[6]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(25)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(4) "text"
|
||||
["name"]=>
|
||||
@@ -151,9 +180,13 @@ array(9) {
|
||||
int(2)
|
||||
}
|
||||
[7]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(1114)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(9) "timestamp"
|
||||
["name"]=>
|
||||
@@ -166,9 +199,13 @@ array(9) {
|
||||
int(2)
|
||||
}
|
||||
[8]=>
|
||||
array(6) {
|
||||
array(8) {
|
||||
["pgsql:oid"]=>
|
||||
int(17)
|
||||
["pgsql:table_oid"]=>
|
||||
int(%d)
|
||||
["table"]=>
|
||||
string(13) "bugtest_62498"
|
||||
["native_type"]=>
|
||||
string(5) "bytea"
|
||||
["name"]=>
|
||||
|
||||
@@ -1483,7 +1483,7 @@ static void ppid2sid(zval *ppid) {
|
||||
PHPAPI void php_session_reset_id(void) /* {{{ */
|
||||
{
|
||||
int module_number = PS(module_number);
|
||||
zval *sid;
|
||||
zval *sid, *data, *ppid;
|
||||
|
||||
if (!PS(id)) {
|
||||
php_error_docref(NULL, E_WARNING, "Cannot set session ID - session ID is not initialized");
|
||||
@@ -1523,13 +1523,20 @@ PHPAPI void php_session_reset_id(void) /* {{{ */
|
||||
}
|
||||
}
|
||||
|
||||
if (APPLY_TRANS_SID) {
|
||||
/* FIXME: Resetting vars are required when
|
||||
session is stop/start/regenerated. However,
|
||||
php_url_scanner_reset_vars() resets all vars
|
||||
including other URL rewrites set by elsewhere. */
|
||||
/* php_url_scanner_reset_vars(); */
|
||||
php_url_scanner_add_var(PS(session_name), strlen(PS(session_name)), ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)), 1);
|
||||
/* Apply trans sid if sid cookie is not set */
|
||||
if (APPLY_TRANS_SID
|
||||
&& (data = zend_hash_str_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE") - 1))) {
|
||||
ZVAL_DEREF(data);
|
||||
if (Z_TYPE_P(data) == IS_ARRAY && (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), strlen(PS(session_name))))) {
|
||||
ZVAL_DEREF(ppid);
|
||||
} else {
|
||||
/* FIXME: Resetting vars are required when
|
||||
session is stop/start/regenerated. However,
|
||||
php_url_scanner_reset_vars() resets all vars
|
||||
including other URL rewrites set by elsewhere. */
|
||||
/* php_url_scanner_reset_vars(); */
|
||||
php_url_scanner_add_var(PS(session_name), strlen(PS(session_name)), ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
23
ext/session/tests/bug71974.phpt
Normal file
23
ext/session/tests/bug71974.phpt
Normal file
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #71974 Trans sid will always be send, even if cookies are available
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--INI--
|
||||
session.save_handler=files
|
||||
session.auto_start=0
|
||||
session.use_cookies=1
|
||||
session.use_only_cookies=0
|
||||
session.use_trans_sid=1
|
||||
session.use_strict_mode=0
|
||||
--COOKIE--
|
||||
PHPSESSID=1234567890123456789012345678901234567890
|
||||
--FILE--
|
||||
<?php
|
||||
ob_start();
|
||||
session_start()
|
||||
?>
|
||||
<a href="some.php">abc</a>
|
||||
--EXPECTF--
|
||||
<a href="some.php">abc</a>
|
||||
|
||||
|
||||
@@ -2000,34 +2000,72 @@ PHP_FUNCTION(array_fill)
|
||||
zval *val;
|
||||
zend_long start_key, num;
|
||||
|
||||
#ifndef FAST_ZPP
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "llz", &start_key, &num, &val) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
ZEND_PARSE_PARAMETERS_START(3, 3)
|
||||
Z_PARAM_LONG(start_key)
|
||||
Z_PARAM_LONG(num)
|
||||
Z_PARAM_ZVAL(val)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
#endif
|
||||
|
||||
if (num < 0) {
|
||||
php_error_docref(NULL, E_WARNING, "Number of elements can't be negative");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* allocate an array for return */
|
||||
array_init_size(return_value, (uint32_t)num);
|
||||
|
||||
if (num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
num--;
|
||||
zend_hash_index_update(Z_ARRVAL_P(return_value), start_key, val);
|
||||
Z_TRY_ADDREF_P(val);
|
||||
|
||||
while (num--) {
|
||||
if (zend_hash_next_index_insert(Z_ARRVAL_P(return_value), val) != NULL) {
|
||||
Z_TRY_ADDREF_P(val);
|
||||
} else {
|
||||
zval_dtor(return_value);
|
||||
if (EXPECTED(num > 0)) {
|
||||
if (sizeof(num) > 4 && UNEXPECTED(EXPECTED(num > 0x7fffffff))) {
|
||||
php_error_docref(NULL, E_WARNING, "Too many elements");
|
||||
RETURN_FALSE;
|
||||
} else if (UNEXPECTED(start_key > ZEND_LONG_MAX - num + 1)) {
|
||||
php_error_docref(NULL, E_WARNING, "Cannot add element to the array as the next element is already occupied");
|
||||
RETURN_FALSE;
|
||||
} else if (EXPECTED(start_key >= 0) && EXPECTED(start_key < num)) {
|
||||
/* create packed array */
|
||||
Bucket *p;
|
||||
zend_long n;
|
||||
|
||||
array_init_size(return_value, (uint32_t)(start_key + num));
|
||||
zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
|
||||
Z_ARRVAL_P(return_value)->nNumUsed = start_key + num;
|
||||
Z_ARRVAL_P(return_value)->nNumOfElements = num;
|
||||
Z_ARRVAL_P(return_value)->nInternalPointer = start_key;
|
||||
|
||||
if (Z_REFCOUNTED_P(val)) {
|
||||
GC_REFCOUNT(Z_COUNTED_P(val)) += num;
|
||||
}
|
||||
|
||||
p = Z_ARRVAL_P(return_value)->arData;
|
||||
n = start_key;
|
||||
|
||||
while (start_key--) {
|
||||
ZVAL_UNDEF(&p->val);
|
||||
p++;
|
||||
}
|
||||
while (num--) {
|
||||
ZVAL_COPY_VALUE(&p->val, val);
|
||||
p->h = n++;
|
||||
p->key = NULL;
|
||||
p++;
|
||||
}
|
||||
} else {
|
||||
/* create hash */
|
||||
array_init_size(return_value, (uint32_t)num);
|
||||
zend_hash_real_init(Z_ARRVAL_P(return_value), 0);
|
||||
if (Z_REFCOUNTED_P(val)) {
|
||||
GC_REFCOUNT(Z_COUNTED_P(val)) += num;
|
||||
}
|
||||
zend_hash_index_add_new(Z_ARRVAL_P(return_value), start_key, val);
|
||||
while (--num) {
|
||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), val);
|
||||
start_key++;
|
||||
}
|
||||
}
|
||||
} else if (EXPECTED(num == 0)) {
|
||||
array_init(return_value);
|
||||
return;
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING, "Number of elements can't be negative");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
Reference in New Issue
Block a user