mirror of
https://github.com/php/php-src.git
synced 2024-09-24 11:27:28 +00:00
Merge branch 'PHP-5.5' of git.php.net:php-src into PHP-5.5
* 'PHP-5.5' of git.php.net:php-src: Fixed bug #63988 (Two Date tests fail) only for PHP-5.5 - Fixed ZTS build Dereferencing process-handles no longer waits on those processes. revert change. now it doesn't compile again...someone should fix ext/date... Use two dtors thus allow allocation based on the alloc model of the connection. plug a leak - forgot ot use the dtor already written Revert "Apply the fputcsv test fix to SplFileObject_fputcsv.phpt. Mea culpa." Revert "Update fputcsv() to escape all characters equally." Add support for connect attributes, as of MySQL 5.6 Bug #62489: dba_insert not working as expected UPGRADING.INTERNALS: document zend_qsort_r Add zend_qsort_r & use it in strtr NEWS for bug #63893 Update README.PARAMETER_PARSING_API Export zend_parse_parameter() Expose zend_parse_arg() as zend_parse_parameter() zend_parse_parameters: allow ! for non pointers
This commit is contained in:
commit
cd619b47f3
12
NEWS
12
NEWS
@ -27,12 +27,19 @@ PHP NEWS
|
||||
|
||||
- DateTime
|
||||
. Added DateTimeImmutable - a variant of DateTime that only returns the
|
||||
modified state instead of changing itself. (Derick)
|
||||
modified state instead of changing itself. (Derick)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #63999 (php with fpm fails to build on Solaris 10 or 11). (Adam)
|
||||
|
||||
- pgsql:
|
||||
. Bug #46408: Locale number format settings can cause pg_query_params to
|
||||
break with numerics. (asmecher, Lars)
|
||||
|
||||
- dba:
|
||||
. Bug #62489: dba_insert not working as expected.
|
||||
(marc-bennewitz at arcor dot de, Lars)
|
||||
|
||||
18 Dec 2012, PHP 5.5.0 Alpha 2
|
||||
|
||||
- General improvements:
|
||||
@ -243,4 +250,7 @@ PHP NEWS
|
||||
. Fixed bug #63248 (Load multiple magic files from a directory under Windows).
|
||||
(Anatoliy)
|
||||
|
||||
- General improvements:
|
||||
. Implemented FR #46487 (Dereferencing process-handles no longer waits on those processes). (Jille Timmermans)
|
||||
|
||||
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
|
||||
|
@ -28,6 +28,17 @@ Both functions return SUCCESS or FAILURE depending on the result.
|
||||
The auto-conversions are performed as necessary. Arrays, objects, and
|
||||
resources cannot be auto-converted.
|
||||
|
||||
PHP 5.5 includes a new function:
|
||||
|
||||
int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, const char *spec, ...);
|
||||
|
||||
This function behaves like zend_parse_parameters_ex() except that instead of
|
||||
reading the arguments from the stack, it receives a single zval to convert
|
||||
(passed with double indirection). The passed zval may be changed in place as
|
||||
part of the conversion process.
|
||||
|
||||
See also https://wiki.php.net/rfc/zpp_improv#expose_zend_parse_arg_as_zend_parse_parameter
|
||||
|
||||
|
||||
Type specifiers
|
||||
---------------
|
||||
@ -65,9 +76,13 @@ Type specifiers
|
||||
will not be touched by the parsing function if they are not
|
||||
passed to it.
|
||||
/ - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
|
||||
! - the parameter it follows can be of specified type or NULL (applies
|
||||
to all specifiers except for 'b', 'l', and 'd'). If NULL is passed, the
|
||||
results pointer is set to NULL as well.
|
||||
! - the parameter it follows can be of specified type or NULL. If NULL is
|
||||
passed and the output for such type is a pointer, then the output
|
||||
pointer is set to a native NULL pointer.
|
||||
For 'b', 'l' and 'd', an extra argument of type zend_bool* must be
|
||||
passed after the corresponding bool*, long* or double* arguments,
|
||||
respectively. A non-zero value will be written to the zend_bool iif a
|
||||
PHP NULL is passed.
|
||||
|
||||
|
||||
Note on 64bit compatibility
|
||||
|
@ -5,6 +5,7 @@ UPGRADE NOTES - PHP X.Y
|
||||
1. Internal API changes
|
||||
a. Streams pooling API
|
||||
b. Lowercasing and locales
|
||||
c. zend_qsort_r
|
||||
|
||||
2. Build system changes
|
||||
a. Unix build system changes
|
||||
@ -53,6 +54,16 @@ such as strcasecmp, will be using locale rules.
|
||||
Two new functions - zend_binary_strncasecmp_l and zend_binary_strcasecmp_l - added as
|
||||
locale-based counterparts to zend_binary_strcasecmp and zend_binary_strncasecmp.
|
||||
|
||||
c. zend_qsort_r
|
||||
|
||||
Added the function zend_qsort_r():
|
||||
|
||||
typedef int (*compare_r_func_t)(const void *, const void * TSRMLS_DC, void *);
|
||||
void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC);
|
||||
|
||||
The extra argument it has (relatively to zend_qsort()) is passed to the
|
||||
comparison function.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
========================
|
||||
|
@ -306,16 +306,14 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
{
|
||||
const char *spec_walk = *spec;
|
||||
char c = *spec_walk++;
|
||||
int return_null = 0;
|
||||
int check_null = 0;
|
||||
|
||||
/* scan through modifiers */
|
||||
while (1) {
|
||||
if (*spec_walk == '/') {
|
||||
SEPARATE_ZVAL_IF_NOT_REF(arg);
|
||||
} else if (*spec_walk == '!') {
|
||||
if (Z_TYPE_PP(arg) == IS_NULL) {
|
||||
return_null = 1;
|
||||
}
|
||||
check_null = 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -327,6 +325,12 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'L':
|
||||
{
|
||||
long *p = va_arg(*va, long *);
|
||||
|
||||
if (check_null) {
|
||||
zend_bool *p = va_arg(*va, zend_bool *);
|
||||
*p = (Z_TYPE_PP(arg) == IS_NULL);
|
||||
}
|
||||
|
||||
switch (Z_TYPE_PP(arg)) {
|
||||
case IS_STRING:
|
||||
{
|
||||
@ -380,6 +384,12 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'd':
|
||||
{
|
||||
double *p = va_arg(*va, double *);
|
||||
|
||||
if (check_null) {
|
||||
zend_bool *p = va_arg(*va, zend_bool *);
|
||||
*p = (Z_TYPE_PP(arg) == IS_NULL);
|
||||
}
|
||||
|
||||
switch (Z_TYPE_PP(arg)) {
|
||||
case IS_STRING:
|
||||
{
|
||||
@ -418,7 +428,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
int *pl = va_arg(*va, int *);
|
||||
switch (Z_TYPE_PP(arg)) {
|
||||
case IS_NULL:
|
||||
if (return_null) {
|
||||
if (check_null) {
|
||||
*p = NULL;
|
||||
*pl = 0;
|
||||
break;
|
||||
@ -462,6 +472,12 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'b':
|
||||
{
|
||||
zend_bool *p = va_arg(*va, zend_bool *);
|
||||
|
||||
if (check_null) {
|
||||
zend_bool *p = va_arg(*va, zend_bool *);
|
||||
*p = (Z_TYPE_PP(arg) == IS_NULL);
|
||||
}
|
||||
|
||||
switch (Z_TYPE_PP(arg)) {
|
||||
case IS_NULL:
|
||||
case IS_STRING:
|
||||
@ -484,7 +500,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'r':
|
||||
{
|
||||
zval **p = va_arg(*va, zval **);
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
*p = NULL;
|
||||
break;
|
||||
}
|
||||
@ -499,7 +515,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'a':
|
||||
{
|
||||
zval **p = va_arg(*va, zval **);
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
*p = NULL;
|
||||
break;
|
||||
}
|
||||
@ -514,7 +530,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'h':
|
||||
{
|
||||
HashTable **p = va_arg(*va, HashTable **);
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
*p = NULL;
|
||||
break;
|
||||
}
|
||||
@ -534,7 +550,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'o':
|
||||
{
|
||||
zval **p = va_arg(*va, zval **);
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
*p = NULL;
|
||||
break;
|
||||
}
|
||||
@ -551,7 +567,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
zval **p = va_arg(*va, zval **);
|
||||
zend_class_entry *ce = va_arg(*va, zend_class_entry *);
|
||||
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
*p = NULL;
|
||||
break;
|
||||
}
|
||||
@ -573,7 +589,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
zend_class_entry **lookup, **pce = va_arg(*va, zend_class_entry **);
|
||||
zend_class_entry *ce_base = *pce;
|
||||
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
*pce = NULL;
|
||||
break;
|
||||
}
|
||||
@ -607,7 +623,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
|
||||
char *is_callable_error = NULL;
|
||||
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
fci->size = 0;
|
||||
fcc->initialized = 0;
|
||||
break;
|
||||
@ -637,7 +653,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'z':
|
||||
{
|
||||
zval **p = va_arg(*va, zval **);
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
*p = NULL;
|
||||
} else {
|
||||
*p = *arg;
|
||||
@ -648,7 +664,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
|
||||
case 'Z':
|
||||
{
|
||||
zval ***p = va_arg(*va, zval ***);
|
||||
if (return_null) {
|
||||
if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
|
||||
*p = NULL;
|
||||
} else {
|
||||
*p = arg;
|
||||
@ -697,6 +713,19 @@ static int zend_parse_arg(int arg_num, zval **arg, va_list *va, const char **spe
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, const char *spec, ...)
|
||||
{
|
||||
va_list va;
|
||||
int ret;
|
||||
int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
|
||||
|
||||
va_start(va, spec);
|
||||
ret = zend_parse_arg(arg_num, arg, &va, &spec, quiet TSRMLS_CC);
|
||||
va_end(va);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, int flags TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
const char *spec_walk;
|
||||
|
@ -258,6 +258,8 @@ ZEND_API char *zend_zval_type_name(const zval *arg);
|
||||
ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr, const char *type_spec, ...);
|
||||
ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args TSRMLS_DC, zval *this_ptr, const char *type_spec, ...);
|
||||
|
||||
ZEND_API int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, const char *spec, ...);
|
||||
|
||||
/* End of parameter parsing API -- andrei */
|
||||
|
||||
ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type TSRMLS_DC);
|
||||
|
@ -19,6 +19,7 @@
|
||||
/* $Id$ */
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_qsort.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
@ -53,7 +54,7 @@ static void _zend_qsort_swap(void *a, void *b, size_t siz)
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC)
|
||||
ZEND_API void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC)
|
||||
{
|
||||
void *begin_stack[QSORT_STACK_SIZE];
|
||||
void *end_stack[QSORT_STACK_SIZE];
|
||||
@ -80,10 +81,10 @@ ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t co
|
||||
seg2 = end;
|
||||
|
||||
while (1) {
|
||||
for (; seg1 < seg2 && compare(begin, seg1 TSRMLS_CC) > 0;
|
||||
for (; seg1 < seg2 && compare(begin, seg1 TSRMLS_CC, arg) > 0;
|
||||
seg1 += siz);
|
||||
|
||||
for (; seg2 >= seg1 && compare(seg2, begin TSRMLS_CC) > 0;
|
||||
for (; seg2 >= seg1 && compare(seg2, begin TSRMLS_CC, arg) > 0;
|
||||
seg2 -= siz);
|
||||
|
||||
if (seg1 >= seg2)
|
||||
@ -117,6 +118,11 @@ ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t co
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC)
|
||||
{
|
||||
zend_qsort_r(base, nmemb, siz, (compare_r_func_t)compare, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
|
@ -22,7 +22,9 @@
|
||||
#define ZEND_QSORT_H
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
typedef int (*compare_r_func_t)(const void *, const void * TSRMLS_DC, void *);
|
||||
ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC);
|
||||
ZEND_API void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC);
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif /* ZEND_QSORT_H */
|
||||
|
@ -2066,12 +2066,12 @@ static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC)
|
||||
return new_ov;
|
||||
}
|
||||
|
||||
static zval* date_clone_immutable(zval *object)
|
||||
static zval* date_clone_immutable(zval *object TSRMLS_DC)
|
||||
{
|
||||
zval *new_object;
|
||||
|
||||
ALLOC_ZVAL(new_object);
|
||||
Z_OBJVAL_P(new_object) = date_object_clone_date(object);
|
||||
Z_OBJVAL_P(new_object) = date_object_clone_date(object TSRMLS_CC);
|
||||
Z_SET_REFCOUNT_P(new_object, 1);
|
||||
Z_SET_ISREF_P(new_object);
|
||||
Z_TYPE_P(new_object) = IS_OBJECT;
|
||||
@ -2883,14 +2883,18 @@ PHP_FUNCTION(date_format)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void php_date_modify(zval *object, char *modify, int modify_len, zval *return_value TSRMLS_DC)
|
||||
static int php_date_modify(zval *object, char *modify, int modify_len TSRMLS_DC)
|
||||
{
|
||||
php_date_obj *dateobj;
|
||||
timelib_time *tmp_time;
|
||||
timelib_error_container *err = NULL;
|
||||
|
||||
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
|
||||
|
||||
if (!(dateobj->time)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The DateTime object has not been correctly initialized by its constructor");
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp_time = timelib_strtotime(modify, modify_len, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
|
||||
|
||||
@ -2901,7 +2905,7 @@ static void php_date_modify(zval *object, char *modify, int modify_len, zval *re
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", modify,
|
||||
err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message);
|
||||
timelib_time_dtor(tmp_time);
|
||||
RETURN_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&dateobj->time->relative, &tmp_time->relative, sizeof(struct timelib_rel_time));
|
||||
@ -2937,6 +2941,8 @@ static void php_date_modify(zval *object, char *modify, int modify_len, zval *re
|
||||
timelib_update_ts(dateobj->time, NULL);
|
||||
timelib_update_from_sse(dateobj->time);
|
||||
dateobj->time->have_relative = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* {{{ proto DateTime date_modify(DateTime object, string modify)
|
||||
@ -2952,9 +2958,11 @@ PHP_FUNCTION(date_modify)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
php_date_modify(object, modify, modify_len, return_value TSRMLS_CC);
|
||||
if (php_date_modify(object, modify, modify_len TSRMLS_CC)) {
|
||||
RETURN_ZVAL(object, 1, 0);
|
||||
}
|
||||
|
||||
RETURN_ZVAL(object, 1, 0);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -2970,10 +2978,12 @@ PHP_METHOD(DateTimeImmutable, modify)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
new_object = date_clone_immutable(object);
|
||||
php_date_modify(new_object, modify, modify_len, return_value TSRMLS_CC);
|
||||
new_object = date_clone_immutable(object TSRMLS_CC);
|
||||
if (php_date_modify(new_object, modify, modify_len TSRMLS_CC)) {
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
}
|
||||
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -3037,7 +3047,7 @@ PHP_METHOD(DateTimeImmutable, add)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
new_object = date_clone_immutable(object);
|
||||
new_object = date_clone_immutable(object TSRMLS_CC);
|
||||
php_date_add(new_object, interval, return_value TSRMLS_CC);
|
||||
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
@ -3107,7 +3117,7 @@ PHP_METHOD(DateTimeImmutable, sub)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
new_object = date_clone_immutable(object);
|
||||
new_object = date_clone_immutable(object TSRMLS_CC);
|
||||
php_date_sub(new_object, interval, return_value TSRMLS_CC);
|
||||
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
@ -3197,7 +3207,7 @@ PHP_METHOD(DateTimeImmutable, setTimezone)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
new_object = date_clone_immutable(object);
|
||||
new_object = date_clone_immutable(object TSRMLS_CC);
|
||||
php_date_timezone_set(new_object, timezone_object, return_value TSRMLS_CC);
|
||||
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
@ -3280,7 +3290,7 @@ PHP_METHOD(DateTimeImmutable, setTime)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
new_object = date_clone_immutable(object);
|
||||
new_object = date_clone_immutable(object TSRMLS_CC);
|
||||
php_date_time_set(new_object, h, i, s, return_value TSRMLS_CC);
|
||||
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
@ -3328,7 +3338,7 @@ PHP_METHOD(DateTimeImmutable, setDate)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
new_object = date_clone_immutable(object);
|
||||
new_object = date_clone_immutable(object TSRMLS_CC);
|
||||
php_date_date_set(new_object, y, m, d, return_value TSRMLS_CC);
|
||||
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
@ -3380,7 +3390,7 @@ PHP_METHOD(DateTimeImmutable, setISODate)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
new_object = date_clone_immutable(object);
|
||||
new_object = date_clone_immutable(object TSRMLS_CC);
|
||||
php_date_isodate_set(new_object, y, w, d, return_value TSRMLS_CC);
|
||||
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
@ -3426,7 +3436,7 @@ PHP_METHOD(DateTimeImmutable, setTimestamp)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
new_object = date_clone_immutable(object);
|
||||
new_object = date_clone_immutable(object TSRMLS_CC);
|
||||
php_date_timestamp_set(new_object, timestamp, return_value TSRMLS_CC);
|
||||
|
||||
RETURN_ZVAL(new_object, 0, 1);
|
||||
|
@ -88,15 +88,16 @@ DBA_UPDATE_FUNC(flatfile)
|
||||
gval.dsize = vallen;
|
||||
|
||||
switch(flatfile_store(dba, gkey, gval, mode==1 ? FLATFILE_INSERT : FLATFILE_REPLACE TSRMLS_CC)) {
|
||||
case -1:
|
||||
php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Operation not possible");
|
||||
return FAILURE;
|
||||
default:
|
||||
case 0:
|
||||
return SUCCESS;
|
||||
case 1:
|
||||
php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Key already exists");
|
||||
return FAILURE;
|
||||
case 0:
|
||||
return SUCCESS;
|
||||
case 1:
|
||||
return FAILURE;
|
||||
case -1:
|
||||
php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Operation not possible");
|
||||
return FAILURE;
|
||||
default:
|
||||
php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "Unknown return value");
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,11 +104,18 @@ DBA_UPDATE_FUNC(gdbm)
|
||||
gval.dptr = (char *) val;
|
||||
gval.dsize = vallen;
|
||||
|
||||
if(gdbm_store(dba->dbf, gkey, gval,
|
||||
mode == 1 ? GDBM_INSERT : GDBM_REPLACE) == 0)
|
||||
return SUCCESS;
|
||||
php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", gdbm_strerror(gdbm_errno));
|
||||
return FAILURE;
|
||||
switch (gdbm_store(dba->dbf, gkey, gval, mode == 1 ? GDBM_INSERT : GDBM_REPLACE)) {
|
||||
case 0:
|
||||
return SUCCESS;
|
||||
case 1:
|
||||
return FAILURE;
|
||||
case -1:
|
||||
php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", gdbm_strerror(gdbm_errno));
|
||||
return FAILURE;
|
||||
default:
|
||||
php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "Unknown return value");
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
DBA_EXISTS_FUNC(gdbm)
|
||||
|
@ -101,7 +101,6 @@ DBA_UPDATE_FUNC(inifile)
|
||||
case 0:
|
||||
return SUCCESS;
|
||||
case 1:
|
||||
php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Key already exists");
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -96,13 +96,15 @@ DBA_FETCH_FUNC(qdbm)
|
||||
DBA_UPDATE_FUNC(qdbm)
|
||||
{
|
||||
QDBM_DATA;
|
||||
int result;
|
||||
|
||||
result = dpput(dba->dbf, key, keylen, val, vallen, mode == 1 ? DP_DKEEP : DP_DOVER);
|
||||
if (result)
|
||||
if (dpput(dba->dbf, key, keylen, val, vallen, mode == 1 ? DP_DKEEP : DP_DOVER)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (dpecode != DP_EKEEP) {
|
||||
php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", dperrmsg(dpecode));
|
||||
}
|
||||
|
||||
php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", dperrmsg(dpecode));
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,8 @@ database handler: db1
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -33,6 +35,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -18,6 +18,8 @@ database handler: db2
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -33,6 +35,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -18,6 +18,8 @@ database handler: db3
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -33,6 +35,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -22,6 +22,8 @@ database handler: db4
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -37,6 +39,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -18,6 +18,8 @@ database handler: dbm
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -33,6 +35,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -22,6 +22,8 @@ database handler: flatfile
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -37,6 +39,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -21,6 +21,8 @@ database handler: gdbm
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write:%sallowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -46,8 +46,16 @@ do {
|
||||
echo "Read during write: allowed\n";
|
||||
}
|
||||
if ($db_writer!==FALSE) {
|
||||
dba_insert("key number 6", "The 6th value", $db_writer);
|
||||
@dba_insert("key number 6", "The 6th value inserted again would be an error", $db_writer);
|
||||
if (dba_insert("key number 6", "The 6th value", $db_writer)) {
|
||||
echo '"key number 6" written' . "\n";
|
||||
} else {
|
||||
echo 'Failed to write "key number 6"' . "\n";
|
||||
}
|
||||
if (dba_insert("key number 6", "The 6th value inserted again would be an error", $db_writer)) {
|
||||
echo '"key number 6" written 2nd time' . "\n";
|
||||
} else {
|
||||
echo 'Failed to write "key number 6" 2nd time' . "\n";
|
||||
}
|
||||
dba_replace("key2", "Content 2 replaced 2nd time", $db_writer);
|
||||
dba_delete("key4", $db_writer);
|
||||
echo dba_fetch("key2", $db_writer)."\n";
|
||||
|
@ -18,6 +18,8 @@ database handler: inifile
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -33,6 +35,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -18,6 +18,8 @@ database handler: ndbm
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -33,6 +35,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -19,6 +19,8 @@ database handler: qdbm
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write:%sallowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -22,6 +22,8 @@ database handler: tcadb
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
@ -37,6 +39,8 @@ array(3) {
|
||||
Content String 2
|
||||
Content 2 replaced
|
||||
Read during write: not allowed
|
||||
"key number 6" written
|
||||
Failed to write "key number 6" 2nd time
|
||||
Content 2 replaced 2nd time
|
||||
The 6th value
|
||||
array(3) {
|
||||
|
@ -95,6 +95,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, free_options)(MYSQLND_CONN_DATA * conn TSRMLS_
|
||||
mnd_pefree(conn->options->cfg_section, pers);
|
||||
conn->options->cfg_section = NULL;
|
||||
}
|
||||
if (conn->options->connect_attr) {
|
||||
zend_hash_destroy(conn->options->connect_attr);
|
||||
mnd_pefree(conn->options->connect_attr, pers);
|
||||
conn->options->connect_attr = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -797,13 +802,14 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
|
||||
goto err;
|
||||
}
|
||||
|
||||
conn->client_flag = mysql_flags;
|
||||
conn->server_capabilities = greet_packet->server_capabilities;
|
||||
|
||||
if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
|
||||
greet_packet, conn->options, mysql_flags TSRMLS_CC))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
conn->client_flag = mysql_flags;
|
||||
conn->server_capabilities = greet_packet->server_capabilities;
|
||||
conn->upsert_status->warning_count = 0;
|
||||
conn->upsert_status->server_status = greet_packet->server_status;
|
||||
conn->upsert_status->affected_rows = 0;
|
||||
@ -811,6 +817,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
|
||||
PACKET_FREE(greet_packet);
|
||||
DBG_RETURN(PASS);
|
||||
err:
|
||||
conn->client_flag = 0;
|
||||
conn->server_capabilities = 0;
|
||||
PACKET_FREE(greet_packet);
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
@ -1086,6 +1094,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn_handle,
|
||||
DBG_ENTER("mysqlnd_conn::connect");
|
||||
|
||||
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
|
||||
mysqlnd_options4(conn_handle, MYSQL_OPT_CONNECT_ATTR_ADD, "_client_name", "mysqlnd");
|
||||
ret = conn->m->connect(conn, host, user, passwd, passwd_len, db, db_len, port, socket_or_pipe, mysql_flags TSRMLS_CC);
|
||||
|
||||
conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
|
||||
@ -1094,6 +1103,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn_handle,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_connect */
|
||||
PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn_handle,
|
||||
const char * host, const char * user,
|
||||
@ -2375,6 +2385,19 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
|
||||
conn->options->flags &= ~CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS;
|
||||
}
|
||||
break;
|
||||
case MYSQL_OPT_CONNECT_ATTR_RESET:
|
||||
if (conn->options->connect_attr) {
|
||||
DBG_INF_FMT("Before reset %d attribute(s)", zend_hash_num_elements(conn->options->connect_attr));
|
||||
zend_hash_clean(conn->options->connect_attr);
|
||||
}
|
||||
break;
|
||||
case MYSQL_OPT_CONNECT_ATTR_DELETE:
|
||||
if (conn->options->connect_attr && value) {
|
||||
DBG_INF_FMT("Before delete %d attribute(s)", zend_hash_num_elements(conn->options->connect_attr));
|
||||
zend_hash_del(conn->options->connect_attr, value, strlen(value));
|
||||
DBG_INF_FMT("%d left", zend_hash_num_elements(conn->options->connect_attr));
|
||||
}
|
||||
break;
|
||||
#ifdef WHEN_SUPPORTED_BY_MYSQLI
|
||||
case MYSQL_SHARED_MEMORY_BASE_NAME:
|
||||
case MYSQL_OPT_USE_RESULT:
|
||||
@ -2395,6 +2418,83 @@ end:
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ connect_attr_item_edtor */
|
||||
static void
|
||||
connect_attr_item_edtor(void * pDest)
|
||||
{
|
||||
#ifdef ZTS
|
||||
TSRMLS_FETCH();
|
||||
#endif
|
||||
DBG_ENTER("connect_attr_item_edtor");
|
||||
mnd_efree(*(char **) pDest);
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ connect_attr_item_pdtor */
|
||||
static void
|
||||
connect_attr_item_pdtor(void * pDest)
|
||||
{
|
||||
#ifdef ZTS
|
||||
TSRMLS_FETCH();
|
||||
#endif
|
||||
DBG_ENTER("connect_attr_item_pdtor");
|
||||
mnd_pefree(*(char **) pDest, 1);
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_conn_data::set_client_option_2d */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)(MYSQLND_CONN_DATA * const conn,
|
||||
enum mysqlnd_option option,
|
||||
const char * const key,
|
||||
const char * const value
|
||||
TSRMLS_DC)
|
||||
{
|
||||
size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, set_client_option_2d);
|
||||
enum_func_status ret = PASS;
|
||||
DBG_ENTER("mysqlnd_conn_data::set_client_option_2d");
|
||||
DBG_INF_FMT("conn=%llu option=%u", conn->thread_id, option);
|
||||
|
||||
if (PASS != conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
|
||||
goto end;
|
||||
}
|
||||
switch (option) {
|
||||
case MYSQL_OPT_CONNECT_ATTR_ADD:
|
||||
if (!conn->options->connect_attr) {
|
||||
DBG_INF("Initializing connect_attr hash");
|
||||
conn->options->connect_attr = mnd_pemalloc(sizeof(HashTable), conn->persistent);
|
||||
if (!conn->options->connect_attr) {
|
||||
goto oom;
|
||||
}
|
||||
zend_hash_init(conn->options->connect_attr, 0, NULL, conn->persistent? connect_attr_item_pdtor:connect_attr_item_edtor, conn->persistent);
|
||||
}
|
||||
DBG_INF_FMT("Adding [%s][%s]", key, value);
|
||||
{
|
||||
const char * copyv = mnd_pestrdup(value, conn->persistent);
|
||||
if (!copyv) {
|
||||
goto oom;
|
||||
}
|
||||
zend_hash_update(conn->options->connect_attr, key, strlen(key), ©v, sizeof(char *), NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = FAIL;
|
||||
}
|
||||
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
|
||||
DBG_RETURN(ret);
|
||||
oom:
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
|
||||
end:
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_conn_data::use_result */
|
||||
static MYSQLND_RES *
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, use_result)(MYSQLND_CONN_DATA * const conn TSRMLS_DC)
|
||||
@ -2662,7 +2762,9 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data)
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags),
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake),
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request),
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, fetch_auth_plugin_by_name)
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, fetch_auth_plugin_by_name),
|
||||
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)
|
||||
MYSQLND_CLASS_METHODS_END;
|
||||
|
||||
|
||||
|
@ -207,6 +207,7 @@ PHPAPI void mysqlnd_set_local_infile_handler(MYSQLND_CONN_DATA * const conn, con
|
||||
#define mysqlnd_set_character_set(conn, cs) ((conn)->data)->m->set_charset((conn)->data, (cs) TSRMLS_CC)
|
||||
#define mysqlnd_stat(conn, msg, msg_len) ((conn)->data)->m->get_server_statistics(((conn)->data), (msg), (msg_len) TSRMLS_CC)
|
||||
#define mysqlnd_options(conn, opt, value) ((conn)->data)->m->set_client_option((conn)->data, (opt), (value) TSRMLS_CC)
|
||||
#define mysqlnd_options4(conn, opt, k, v) ((conn)->data)->m->set_client_option_2d((conn)->data, (opt), (k), (v) TSRMLS_CC)
|
||||
#define mysqlnd_set_server_option(conn, op) ((conn)->data)->m->set_server_option((conn)->data, (op) TSRMLS_CC)
|
||||
|
||||
/* Escaping */
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "mysqlnd_charset.h"
|
||||
#include "mysqlnd_debug.h"
|
||||
|
||||
|
||||
/* {{{ mysqlnd_auth_handshake */
|
||||
enum_func_status
|
||||
mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
|
||||
@ -99,6 +98,10 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
|
||||
auth_packet->auth_data = auth_plugin_data;
|
||||
auth_packet->auth_data_len = auth_plugin_data_len;
|
||||
auth_packet->auth_plugin_name = auth_protocol;
|
||||
|
||||
if (conn->server_capabilities & CLIENT_CONNECT_ATTRS) {
|
||||
auth_packet->connect_attr = conn->options->connect_attr;
|
||||
}
|
||||
|
||||
if (!PACKET_WRITE(auth_packet, conn)) {
|
||||
goto end;
|
||||
|
@ -168,6 +168,9 @@ typedef enum mysqlnd_option
|
||||
MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
||||
MYSQL_PLUGIN_DIR,
|
||||
MYSQL_DEFAULT_AUTH,
|
||||
MYSQL_OPT_CONNECT_ATTR_RESET,
|
||||
MYSQL_OPT_CONNECT_ATTR_ADD,
|
||||
MYSQL_OPT_CONNECT_ATTR_DELETE,
|
||||
MYSQL_SERVER_PUBLIC_KEY,
|
||||
MYSQL_ENABLE_CLEARTEXT_PLUGIN,
|
||||
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
|
||||
|
@ -106,7 +106,8 @@
|
||||
#define mysql_stmt_more_results(s) mysqlnd_stmt_more_results((s))
|
||||
#define mysql_thread_safe() mysqlnd_thread_safe()
|
||||
#define mysql_info(r) mysqlnd_info((r))
|
||||
#define mysql_options(r,a,b) mysqlnd_options((r), (a), (b))
|
||||
#define mysql_options(c,a,v) mysqlnd_options((c), (a), (v))
|
||||
#define mysql_options4(c,a,k,v) mysqlnd_options4((c), (a), (k), (v))
|
||||
#define mysql_stmt_init(r) mysqlnd_stmt_init((r))
|
||||
#define mysql_free_result(r) mysqlnd_free_result((r), FALSE)
|
||||
#define mysql_store_result(r) mysqlnd_store_result((r))
|
||||
|
@ -172,7 +172,7 @@ typedef struct st_mysqlnd_options
|
||||
The ABI will be broken and the methods structure will be somewhere else
|
||||
in the memory which can crash external code. Feel free to reuse these.
|
||||
*/
|
||||
char * unused2;
|
||||
HashTable * connect_attr;
|
||||
char * unused3;
|
||||
char * unused4;
|
||||
char * unused5;
|
||||
@ -489,6 +489,8 @@ typedef enum_func_status (*func_mysqlnd_conn_data__connect_handshake)(MYSQLND_CO
|
||||
typedef enum_func_status (*func_mysqlnd_conn_data__simple_command_send_request)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command, const zend_uchar * const arg, size_t arg_len, zend_bool silent, zend_bool ignore_upsert_status TSRMLS_DC);
|
||||
typedef struct st_mysqlnd_authentication_plugin * (*func_mysqlnd_conn_data__fetch_auth_plugin_by_name)(const char * const requested_protocol TSRMLS_DC);
|
||||
|
||||
typedef enum_func_status (*func_mysqlnd_conn_data__set_client_option_2d)(MYSQLND_CONN_DATA * const conn, enum mysqlnd_option option, const char * const key, const char * const value TSRMLS_DC);
|
||||
|
||||
struct st_mysqlnd_conn_data_methods
|
||||
{
|
||||
func_mysqlnd_conn_data__init init;
|
||||
@ -573,6 +575,8 @@ struct st_mysqlnd_conn_data_methods
|
||||
func_mysqlnd_conn_data__connect_handshake connect_handshake;
|
||||
func_mysqlnd_conn_data__simple_command_send_request simple_command_send_request;
|
||||
func_mysqlnd_conn_data__fetch_auth_plugin_by_name fetch_auth_plugin_by_name;
|
||||
|
||||
func_mysqlnd_conn_data__set_client_option_2d set_client_option_2d;
|
||||
};
|
||||
|
||||
|
||||
|
@ -212,6 +212,24 @@ php_mysqlnd_net_store_length(zend_uchar *packet, uint64_t length)
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ php_mysqlnd_net_store_length_size */
|
||||
size_t
|
||||
php_mysqlnd_net_store_length_size(uint64_t length)
|
||||
{
|
||||
if (length < (uint64_t) L64(251)) {
|
||||
return 1;
|
||||
}
|
||||
if (length < (uint64_t) L64(65536)) {
|
||||
return 3;
|
||||
}
|
||||
if (length < (uint64_t) L64(16777216)) {
|
||||
return 4;
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ php_mysqlnd_read_error_from_line */
|
||||
static enum_func_status
|
||||
php_mysqlnd_read_error_from_line(zend_uchar *buf, size_t buf_len,
|
||||
@ -459,7 +477,7 @@ void php_mysqlnd_greet_free_mem(void * _packet, zend_bool stack_allocation TSRML
|
||||
/* }}} */
|
||||
|
||||
|
||||
#define AUTH_WRITE_BUFFER_LEN (MYSQLND_HEADER_SIZE + MYSQLND_MAX_ALLOWED_USER_LEN + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 1024)
|
||||
#define AUTH_WRITE_BUFFER_LEN (MYSQLND_HEADER_SIZE + MYSQLND_MAX_ALLOWED_USER_LEN + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 4096)
|
||||
|
||||
/* {{{ php_mysqlnd_auth_write */
|
||||
static
|
||||
@ -540,6 +558,52 @@ size_t php_mysqlnd_auth_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC
|
||||
p+= len;
|
||||
*p++= '\0';
|
||||
}
|
||||
|
||||
if (packet->connect_attr && zend_hash_num_elements(packet->connect_attr)) {
|
||||
HashPosition pos_value;
|
||||
const char ** entry_value;
|
||||
size_t ca_payload_len = 0;
|
||||
zend_hash_internal_pointer_reset_ex(packet->connect_attr, &pos_value);
|
||||
while (SUCCESS == zend_hash_get_current_data_ex(packet->connect_attr, (void **)&entry_value, &pos_value)) {
|
||||
char *s_key;
|
||||
unsigned int s_len;
|
||||
unsigned long num_key;
|
||||
size_t value_len = strlen(*entry_value);
|
||||
|
||||
if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(packet->connect_attr, &s_key, &s_len, &num_key, 0, &pos_value)) {
|
||||
ca_payload_len += php_mysqlnd_net_store_length_size(s_len);
|
||||
ca_payload_len += s_len;
|
||||
ca_payload_len += php_mysqlnd_net_store_length_size(value_len);
|
||||
ca_payload_len += value_len;
|
||||
}
|
||||
zend_hash_move_forward_ex(conn->options->connect_attr, &pos_value);
|
||||
}
|
||||
|
||||
if ((sizeof(buffer) - (p - buffer)) >= (ca_payload_len + php_mysqlnd_net_store_length_size(ca_payload_len))) {
|
||||
p = php_mysqlnd_net_store_length(p, ca_payload_len);
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(packet->connect_attr, &pos_value);
|
||||
while (SUCCESS == zend_hash_get_current_data_ex(packet->connect_attr, (void **)&entry_value, &pos_value)) {
|
||||
char *s_key;
|
||||
unsigned int s_len;
|
||||
unsigned long num_key;
|
||||
size_t value_len = strlen(*entry_value);
|
||||
if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(packet->connect_attr, &s_key, &s_len, &num_key, 0, &pos_value)) {
|
||||
/* copy key */
|
||||
p = php_mysqlnd_net_store_length(p, s_len);
|
||||
memcpy(p, s_key, s_len);
|
||||
p+= s_len;
|
||||
/* copy value */
|
||||
p = php_mysqlnd_net_store_length(p, value_len);
|
||||
memcpy(p, *entry_value, value_len);
|
||||
p+= value_len;
|
||||
}
|
||||
zend_hash_move_forward_ex(conn->options->connect_attr, &pos_value);
|
||||
}
|
||||
} else {
|
||||
/* cannot put the data - skip */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packet->is_change_user_packet) {
|
||||
if (PASS != conn->m->simple_command(conn, COM_CHANGE_USER, buffer + MYSQLND_HEADER_SIZE, p - buffer - MYSQLND_HEADER_SIZE,
|
||||
|
@ -103,7 +103,7 @@ typedef struct st_mysqlnd_packet_auth {
|
||||
zend_bool send_auth_data;
|
||||
zend_bool is_change_user_packet;
|
||||
zend_bool silent;
|
||||
|
||||
HashTable *connect_attr;
|
||||
} MYSQLND_PACKET_AUTH;
|
||||
|
||||
/* Auth response packet */
|
||||
|
@ -159,6 +159,7 @@ static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
|
||||
static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
|
||||
{
|
||||
FG(pclose_ret) = 0;
|
||||
FG(pclose_wait) = 0;
|
||||
FG(user_stream_current_filename) = NULL;
|
||||
FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
|
||||
FG(wrapper_errors) = NULL;
|
||||
@ -960,7 +961,9 @@ PHP_FUNCTION(pclose)
|
||||
|
||||
PHP_STREAM_TO_ZVAL(stream, &arg1);
|
||||
|
||||
FG(pclose_wait) = 1;
|
||||
zend_list_delete(stream->rsrc_id);
|
||||
FG(pclose_wait) = 0;
|
||||
RETURN_LONG(FG(pclose_ret));
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -115,7 +115,7 @@ typedef struct _php_meta_tags_data {
|
||||
php_meta_tags_token php_next_meta_token(php_meta_tags_data * TSRMLS_DC);
|
||||
|
||||
typedef struct {
|
||||
int pclose_ret;
|
||||
int pclose_ret;
|
||||
size_t def_chunk_size;
|
||||
long auto_detect_line_endings;
|
||||
long default_socket_timeout;
|
||||
@ -126,6 +126,7 @@ typedef struct {
|
||||
HashTable *stream_wrappers; /* per-request copy of url_stream_wrappers_hash */
|
||||
HashTable *stream_filters; /* per-request copy of stream_filters_hash */
|
||||
HashTable *wrapper_errors; /* key: wrapper address; value: linked list of char* */
|
||||
int pclose_wait;
|
||||
} php_file_globals;
|
||||
|
||||
#ifdef ZTS
|
||||
|
@ -208,6 +208,7 @@ static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
DWORD wstatus;
|
||||
#elif HAVE_SYS_WAIT_H
|
||||
int wstatus;
|
||||
int waitpid_options = 0;
|
||||
pid_t wait_pid;
|
||||
#endif
|
||||
|
||||
@ -220,18 +221,27 @@ static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
}
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
WaitForSingleObject(proc->childHandle, INFINITE);
|
||||
if (FG(pclose_wait)) {
|
||||
WaitForSingleObject(proc->childHandle, INFINITE);
|
||||
}
|
||||
GetExitCodeProcess(proc->childHandle, &wstatus);
|
||||
FG(pclose_ret) = wstatus;
|
||||
if (wstatus == STILL_ACTIVE) {
|
||||
FG(pclose_ret) = -1;
|
||||
} else {
|
||||
FG(pclose_ret) = wstatus;
|
||||
}
|
||||
CloseHandle(proc->childHandle);
|
||||
|
||||
#elif HAVE_SYS_WAIT_H
|
||||
|
||||
if (!FG(pclose_wait)) {
|
||||
waitpid_options = WNOHANG;
|
||||
}
|
||||
do {
|
||||
wait_pid = waitpid(proc->child, &wstatus, 0);
|
||||
wait_pid = waitpid(proc->child, &wstatus, waitpid_options);
|
||||
} while (wait_pid == -1 && errno == EINTR);
|
||||
|
||||
if (wait_pid == -1) {
|
||||
if (wait_pid <= 0) {
|
||||
FG(pclose_ret) = -1;
|
||||
} else {
|
||||
if (WIFEXITED(wstatus))
|
||||
@ -300,7 +310,9 @@ PHP_FUNCTION(proc_close)
|
||||
|
||||
ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, &zproc, -1, "process", le_proc_open);
|
||||
|
||||
FG(pclose_wait) = 1;
|
||||
zend_list_delete(Z_LVAL_P(zproc));
|
||||
FG(pclose_wait) = 0;
|
||||
RETURN_LONG(FG(pclose_ret));
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -2851,7 +2851,7 @@ static inline void php_strtr_populate_shift(PATNREPL *patterns, int patnum, int
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ php_strtr_compare_hash_suffix */
|
||||
static int php_strtr_compare_hash_suffix(const void *a, const void *b, void *ctx_g)
|
||||
static int php_strtr_compare_hash_suffix(const void *a, const void *b TSRMLS_DC, void *ctx_g)
|
||||
{
|
||||
const PPRES *res = ctx_g;
|
||||
const PATNREPL *pnr_a = a,
|
||||
@ -2877,62 +2877,6 @@ static int php_strtr_compare_hash_suffix(const void *a, const void *b, void *ctx
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ Sorting (no zend_qsort_r in this PHP version) */
|
||||
#define HS_LEFT(i) ((i) * 2 + 1)
|
||||
#define HS_RIGHT(i) ((i) * 2 + 2)
|
||||
#define HS_PARENT(i) (((i) - 1) / 2);
|
||||
#define HS_OFF(data, i) ((void *)(&((data)->arr)[i]))
|
||||
#define HS_CMP_CALL(data, i1, i2) \
|
||||
(php_strtr_compare_hash_suffix(HS_OFF((data), (i1)), HS_OFF((data), (i2)), (data)->res))
|
||||
struct hs_data {
|
||||
PATNREPL *arr;
|
||||
size_t nel;
|
||||
size_t heapel;
|
||||
PPRES *res;
|
||||
};
|
||||
static inline void php_strtr_swap(PATNREPL *a, PATNREPL *b)
|
||||
{
|
||||
PATNREPL tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
static inline void php_strtr_fix_heap(struct hs_data *data, size_t i)
|
||||
{
|
||||
size_t li = HS_LEFT(i),
|
||||
ri = HS_RIGHT(i),
|
||||
largei;
|
||||
if (li < data->heapel && HS_CMP_CALL(data, li, i) > 0) {
|
||||
largei = li;
|
||||
} else {
|
||||
largei = i;
|
||||
}
|
||||
if (ri < data->heapel && HS_CMP_CALL(data, ri, largei) > 0) {
|
||||
largei = ri;
|
||||
}
|
||||
if (largei != i) {
|
||||
php_strtr_swap(HS_OFF(data, i), HS_OFF(data, largei));
|
||||
php_strtr_fix_heap(data, largei);
|
||||
}
|
||||
}
|
||||
static inline void php_strtr_build_heap(struct hs_data *data)
|
||||
{
|
||||
size_t i;
|
||||
for (i = data->nel / 2; i > 0; i--) {
|
||||
php_strtr_fix_heap(data, i - 1);
|
||||
}
|
||||
}
|
||||
static inline void php_strtr_heapsort(PATNREPL *arr, size_t nel, PPRES *res)
|
||||
{
|
||||
struct hs_data data = { arr, nel, nel, res };
|
||||
size_t i;
|
||||
php_strtr_build_heap(&data);
|
||||
for (i = nel; i > 1; i--) {
|
||||
php_strtr_swap(arr, HS_OFF(&data, i - 1));
|
||||
data.heapel--;
|
||||
php_strtr_fix_heap(&data, 0);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ php_strtr_free_strp */
|
||||
static void php_strtr_free_strp(void *strp)
|
||||
{
|
||||
@ -3030,7 +2974,13 @@ static PPRES *php_strtr_array_prepare(STR *text, PATNREPL *patterns, int patnum,
|
||||
|
||||
res->patterns = safe_emalloc(patnum, sizeof(*res->patterns), 0);
|
||||
memcpy(res->patterns, patterns, sizeof(*patterns) * patnum);
|
||||
php_strtr_heapsort(res->patterns, patnum, res);
|
||||
#ifdef ZTS
|
||||
zend_qsort_r(res->patterns, patnum, sizeof(*res->patterns),
|
||||
php_strtr_compare_hash_suffix, res, NULL); /* tsrmls not needed */
|
||||
#else
|
||||
zend_qsort_r(res->patterns, patnum, sizeof(*res->patterns),
|
||||
php_strtr_compare_hash_suffix, res);
|
||||
#endif
|
||||
|
||||
res->prefix = safe_emalloc(patnum, sizeof(*res->prefix), 0);
|
||||
for (i = 0; i < patnum; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user