1
0
mirror of https://github.com/php/php-src.git synced 2026-04-24 00:18:23 +02:00
This commit is contained in:
Joe Watkins
2016-01-20 10:55:09 +00:00
47 changed files with 796 additions and 124 deletions
+5
View File
@@ -95,6 +95,11 @@ PHP 7.1 UPGRADE NOTES
- Core:
. Support for ftok()
- FCGI
. PHP_FCGI_CHILDREN is respected. If this environment variable is defined,
the first php-fcgi.exe process will exec the specified number of children.
Those will share the same TCP socket.
========================================
13. Other Changes
========================================
+1 -1
View File
@@ -284,7 +284,7 @@ char *alloca();
# endif
# elif defined(_MSC_VER)
# define zend_always_inline __forceinline
# define zend_never_inline
# define zend_never_inline __declspec(noinline)
# else
# if __has_attribute(always_inline)
# define zend_always_inline inline __attribute__((always_inline))
@@ -278,7 +278,7 @@ retry:
w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min];
} else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) {
w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min];
} else if (s >= cp932ext3_ucs_table_min && s < cp932ext2_ucs_table_max) {
} else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) {
w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min];
} else if (s >= 94 * 94 && s < 114 * 94) {
/* user-defined => PUA (Microsoft extended) */
+2 -1
View File
@@ -4145,9 +4145,10 @@ PHP_FUNCTION(mb_send_mail)
suppressed_hdrs.cnt_type = 1;
}
if ((s = zend_hash_str_find_ptr(&ht_headers, "CONTENT-TRANSFER-ENCODING", sizeof("CONTENT-TRANSFER-ENCODING") - 1))) {
if ((s = zend_hash_str_find(&ht_headers, "CONTENT-TRANSFER-ENCODING", sizeof("CONTENT-TRANSFER-ENCODING") - 1))) {
enum mbfl_no_encoding _body_enc;
ZEND_ASSERT(Z_TYPE_P(s) == IS_STRING);
_body_enc = mbfl_name2no_encoding(Z_STRVAL_P(s));
switch (_body_enc) {
case mbfl_no_encoding_base64:
+28 -12
View File
@@ -40,7 +40,7 @@ PHPAPI const char * const mysqlnd_server_gone = "MySQL server has gone away";
PHPAPI const char * const mysqlnd_out_of_sync = "Commands out of sync; you can't run this command now";
PHPAPI const char * const mysqlnd_out_of_memory = "Out of memory";
PHPAPI MYSQLND_STATS *mysqlnd_global_stats = NULL;
PHPAPI MYSQLND_STATS * mysqlnd_global_stats = NULL;
/* {{{ mysqlnd_upsert_status::reset */
@@ -152,8 +152,8 @@ MYSQLND_CLASS_METHODS_END;
/* {{{ mysqlnd_error_info_init */
enum_func_status
mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, zend_bool persistent)
PHPAPI enum_func_status
mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, const zend_bool persistent)
{
DBG_ENTER("mysqlnd_error_info_init");
info->m = mysqlnd_error_info_get_methods();
@@ -163,12 +163,28 @@ mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, zend_bool persistent)
if (info->error_list) {
zend_llist_init(info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, persistent);
}
info->persistent = persistent;
DBG_RETURN(info->error_list? PASS:FAIL);
}
/* }}} */
/* {{{ mysqlnd_error_info_free_contents */
PHPAPI void
mysqlnd_error_info_free_contents(MYSQLND_ERROR_INFO * const info)
{
DBG_ENTER("mysqlnd_error_info_free_contents");
info->m->reset(info);
if (info->error_list) {
mnd_pefree(info->error_list, info->persistent);
info->error_list = NULL;
}
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ mysqlnd_connection_state::get */
@@ -200,10 +216,8 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_connection_state)
MYSQLND_CLASS_METHODS_END;
/* {{{ mysqlnd_upsert_status_init */
void
PHPAPI void
mysqlnd_connection_state_init(struct st_mysqlnd_connection_state * const state)
{
DBG_ENTER("mysqlnd_error_info_init");
@@ -214,6 +228,7 @@ mysqlnd_connection_state_init(struct st_mysqlnd_connection_state * const state)
/* }}} */
/* {{{ mysqlnd_conn_data::free_options */
static void
MYSQLND_METHOD(mysqlnd_conn_data, free_options)(MYSQLND_CONN_DATA * conn)
@@ -318,11 +333,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, free_contents)(MYSQLND_CONN_DATA * conn)
mnd_pefree(conn->last_message.s, pers);
conn->last_message.s = NULL;
}
if (conn->error_info->error_list) {
zend_llist_clean(conn->error_info->error_list);
mnd_pefree(conn->error_info->error_list, pers);
conn->error_info->error_list = NULL;
}
conn->charset = NULL;
conn->greet_charset = NULL;
@@ -341,6 +352,11 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn_data, dtor)(MYSQLND_CONN_DATA * conn)
conn->m->free_contents(conn);
conn->m->free_options(conn);
if (conn->error_info) {
mysqlnd_error_info_free_contents(conn->error_info);
conn->error_info = NULL;
}
if (conn->protocol_frame_codec) {
mysqlnd_pfc_free(conn->protocol_frame_codec, conn->stats, conn->error_info);
conn->protocol_frame_codec = NULL;
+3 -2
View File
@@ -67,12 +67,13 @@ void mysqlnd_upsert_status_init(MYSQLND_UPSERT_STATUS * const upsert_status);
}
enum_func_status mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, zend_bool persistent);
PHPAPI enum_func_status mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, const zend_bool persistent);
PHPAPI void mysqlnd_error_info_free_contents(MYSQLND_ERROR_INFO * const info);
#define GET_CONNECTION_STATE(state_struct) (state_struct)->m->get((state_struct))
#define SET_CONNECTION_STATE(state_struct, s) (state_struct)->m->set((state_struct), (s))
void mysqlnd_connection_state_init(struct st_mysqlnd_connection_state * const state);
PHPAPI void mysqlnd_connection_state_init(struct st_mysqlnd_connection_state * const state);
#endif /* MYSQLND_CONNECTION_H */
+4
View File
@@ -32,6 +32,9 @@
#define MYSQLND_CLASS_METHODS_START(class) MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(class) = {
#define MYSQLND_CLASS_METHODS_END }
#define MYSQLND_CLASS_METHODS_INSTANCE_NAME(class) mysqlnd_##class##_methods_ptr
#define MYSQLND_CLASS_METHODS_INSTANCE_DECLARE(class) extern const MYSQLND_CLASS_METHODS_TYPE(class) * MYSQLND_CLASS_METHODS_INSTANCE_NAME(class)
#define MYSQLND_CLASS_METHODS_INSTANCE_DEFINE(class) const MYSQLND_CLASS_METHODS_TYPE(class) * MYSQLND_CLASS_METHODS_INSTANCE_NAME(class) = & MYSQLND_CLASS_METHOD_TABLE_NAME(class)
typedef struct st_mysqlnd_string
{
@@ -154,6 +157,7 @@ struct st_mysqlnd_error_info
unsigned int error_no;
zend_llist * error_list;
zend_bool persistent;
MYSQLND_CLASS_METHODS_TYPE(mysqlnd_error_info) *m;
};
+7 -1
View File
@@ -34,6 +34,11 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx,
{
uint32_t build_flags;
if (op_array->last_try_catch) {
/* TODO: we can't analyze functions with try/catch/finally ??? */
return FAILURE;
}
/* Build SSA */
memset(ssa, 0, sizeof(zend_ssa));
@@ -41,7 +46,8 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx,
return FAILURE;
}
if (*flags & ZEND_FUNC_TOO_DYNAMIC) {
if (*flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) {
/* TODO: we can't analyze functions with indirect variable access ??? */
return FAILURE;
}
+14 -18
View File
@@ -251,10 +251,6 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
/* Build CFG, Step 1: Find basic blocks starts, calculate number of blocks */
BB_START(0);
if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->static_variables) {
// FIXME: Really we should try to perform variable initialization
flags |= ZEND_FUNC_TOO_DYNAMIC;
}
for (i = 0; i < op_array->last; i++) {
zend_op *opline = op_array->opcodes + i;
switch(opline->opcode) {
@@ -268,9 +264,9 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
}
break;
case ZEND_INCLUDE_OR_EVAL:
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
case ZEND_YIELD:
case ZEND_YIELD_FROM:
flags |= ZEND_FUNC_TOO_DYNAMIC;
if (build_flags & ZEND_CFG_STACKLESS) {
BB_START(i + 1);
}
@@ -296,15 +292,17 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
if ((fn = zend_hash_find_ptr(EG(function_table), Z_STR_P(zv))) != NULL) {
if (fn->type == ZEND_INTERNAL_FUNCTION) {
if (zend_string_equals_literal(Z_STR_P(zv), "extract")) {
flags |= ZEND_FUNC_TOO_DYNAMIC;
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
} else if (zend_string_equals_literal(Z_STR_P(zv), "compact")) {
flags |= ZEND_FUNC_TOO_DYNAMIC;
} else if (zend_string_equals_literal(Z_STR_P(zv), "parse_str")) {
flags |= ZEND_FUNC_TOO_DYNAMIC;
} else if (zend_string_equals_literal(Z_STR_P(zv), "mb_parse_str")) {
flags |= ZEND_FUNC_TOO_DYNAMIC;
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
} else if (zend_string_equals_literal(Z_STR_P(zv), "parse_str") &&
opline->extended_value == 1) {
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
} else if (zend_string_equals_literal(Z_STR_P(zv), "mb_parse_str") &&
opline->extended_value == 1) {
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
} else if (zend_string_equals_literal(Z_STR_P(zv), "get_defined_vars")) {
flags |= ZEND_FUNC_TOO_DYNAMIC;
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
} else if (zend_string_equals_literal(Z_STR_P(zv), "func_num_args")) {
flags |= ZEND_FUNC_VARARG;
} else if (zend_string_equals_literal(Z_STR_P(zv), "func_get_arg")) {
@@ -316,12 +314,10 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
}
break;
case ZEND_FAST_CALL:
flags |= ZEND_FUNC_TOO_DYNAMIC;
BB_START(OP_JMP_ADDR(opline, opline->op1) - op_array->opcodes);
BB_START(i + 1);
break;
case ZEND_FAST_RET:
flags |= ZEND_FUNC_TOO_DYNAMIC;
if (i + 1 < op_array->last) {
BB_START(i + 1);
}
@@ -350,7 +346,6 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
BB_START(i + 1);
break;
case ZEND_CATCH:
flags |= ZEND_FUNC_TOO_DYNAMIC;
if (!opline->result.num) {
BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
}
@@ -370,8 +365,9 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
BB_START(i + 1);
break;
case ZEND_UNSET_VAR:
case ZEND_ISSET_ISEMPTY_VAR:
if (!(opline->extended_value & ZEND_QUICK_SET)) {
flags |= ZEND_FUNC_TOO_DYNAMIC;
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
}
break;
case ZEND_FETCH_R:
@@ -381,11 +377,11 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
case ZEND_FETCH_IS:
case ZEND_FETCH_UNSET:
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_LOCAL) {
flags |= ZEND_FUNC_TOO_DYNAMIC;
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
} else if (((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_GLOBAL ||
(opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_GLOBAL_LOCK) &&
!op_array->function_name) {
flags |= ZEND_FUNC_TOO_DYNAMIC;
flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
}
break;
}
+11 -2
View File
@@ -305,8 +305,14 @@ void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int s
}
}
static void zend_dump_pi_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_pi_range *r)
static void zend_dump_pi_constraint(const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_pi_constraint *r)
{
if (r->type_mask != (uint32_t) -1) {
fprintf(stderr, " TYPE");
zend_dump_type_info(r->type_mask, NULL, 0);
return;
}
if (r->range.underflow && r->range.overflow) {
return;
}
@@ -791,7 +797,7 @@ static void zend_dump_block_header(const zend_cfg *cfg, const zend_op_array *op_
fprintf(stderr, " = Pi(");
zend_dump_ssa_var(op_array, ssa, p->sources[0], 0, p->var);
fprintf(stderr, " &");
zend_dump_pi_range(op_array, ssa, &p->constraint);
zend_dump_pi_constraint(op_array, ssa, &p->constraint);
fprintf(stderr, ")\n");
}
p = p->next;
@@ -853,6 +859,9 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons
if (ssa) {
fprintf(stderr, ", ssa_vars=%d", ssa->vars_count);
}
if (func_flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) {
fprintf(stderr, ", dynamic");
}
if (func_flags & ZEND_FUNC_RECURSIVE) {
fprintf(stderr, ", recursive");
if (func_flags & ZEND_FUNC_RECURSIVE_DIRECTLY) {
+1 -1
View File
@@ -22,7 +22,7 @@
#include "zend_ssa.h"
/* func flags */
#define ZEND_FUNC_TOO_DYNAMIC (1<<0)
#define ZEND_FUNC_INDIRECT_VAR_ACCESS (1<<0)
#define ZEND_FUNC_HAS_CALLS (1<<1)
#define ZEND_FUNC_VARARG (1<<2)
#define ZEND_FUNC_NO_LOOPS (1<<3)
+23 -11
View File
@@ -475,7 +475,7 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
tmp->min = ZEND_LONG_MAX;
tmp->max = ZEND_LONG_MIN;
tmp->overflow = 0;
if (p->pi >= 0) {
if (p->pi >= 0 && p->constraint.type_mask == (uint32_t) -1) {
if (p->constraint.negative) {
if (ssa->var_info[p->sources[0]].has_range) {
tmp->underflow = ssa->var_info[p->sources[0]].range.underflow;
@@ -1814,6 +1814,7 @@ static void zend_infer_ranges_warmup(const zend_op_array *op_array, zend_ssa *ss
ssa->var_info[j].has_range &&
ssa->vars[j].definition_phi &&
ssa->vars[j].definition_phi->pi >= 0 &&
ssa->vars[j].definition_phi->constraint.type_mask == (uint32_t) -1 &&
ssa->vars[j].definition_phi->constraint.negative &&
ssa->vars[j].definition_phi->constraint.min_ssa_var < 0 &&
ssa->vars[j].definition_phi->constraint.min_ssa_var < 0) {
@@ -3067,8 +3068,11 @@ static void zend_update_type_info(const zend_op_array *op_array,
}
break;
case ZEND_BIND_GLOBAL:
tmp = (MAY_BE_REF | MAY_BE_ANY);
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
break;
case ZEND_BIND_STATIC:
tmp = (MAY_BE_REF | MAY_BE_ANY );
tmp = MAY_BE_ANY | (opline->extended_value ? MAY_BE_REF : (MAY_BE_RC1 | MAY_BE_RCN));
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
break;
case ZEND_SEND_VAR:
@@ -3655,6 +3659,9 @@ int zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script
zend_ssa_phi *p = ssa_vars[j].definition_phi;
if (p->pi >= 0) {
tmp = get_ssa_var_info(ssa, p->sources[0]);
if (p->constraint.type_mask != (uint32_t) -1) {
tmp &= p->constraint.type_mask;
}
UPDATE_SSA_TYPE(tmp, j);
if (ssa_var_info[p->sources[0]].ce) {
UPDATE_SSA_OBJ_TYPE(ssa_var_info[p->sources[0]].ce, ssa_var_info[p->sources[0]].is_instanceof, j);
@@ -4071,17 +4078,22 @@ int zend_ssa_inference(zend_arena **arena, const zend_op_array *op_array, const
}
ssa_var_info = ssa->var_info;
for (i = 0; i < op_array->last_var; i++) {
if (!op_array->function_name) {
if (!op_array->function_name) {
for (i = 0; i < op_array->last_var; i++) {
ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
} else if (i == EX_VAR_TO_NUM(op_array->this_var)) {
ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_OBJECT;
ssa_var_info[i].ce = op_array->scope;
ssa_var_info[i].is_instanceof = 1;
} else {
ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RCN;
ssa_var_info[i].has_range = 0;
}
} else {
for (i = 0; i < op_array->last_var; i++) {
if (i == EX_VAR_TO_NUM(op_array->this_var)) {
ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_OBJECT;
ssa_var_info[i].ce = op_array->scope;
ssa_var_info[i].is_instanceof = 1;
} else {
ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RCN;
}
ssa_var_info[i].has_range = 0;
}
ssa_var_info[i].has_range = 0;
}
for (i = op_array->last_var; i < ssa->vars_count; i++) {
ssa_var_info[i].type = 0;
+76
View File
@@ -21,6 +21,7 @@
#include "zend_dfg.h"
#include "zend_ssa.h"
#include "zend_dump.h"
#include "zend_inference.h"
static int needs_pi(const zend_op_array *op_array, zend_dfg *dfg, zend_ssa *ssa, int from, int to, int var) /* {{{ */
{
@@ -78,6 +79,7 @@ static void pi_range(
phi->constraint.range.underflow = underflow;
phi->constraint.range.overflow = overflow;
phi->constraint.negative = negative ? NEG_INIT : NEG_NONE;
phi->constraint.type_mask = (uint32_t) -1;
}
/* }}} */
@@ -94,6 +96,27 @@ static inline void pi_range_max(zend_ssa_phi *phi, int var, zend_long val) {
pi_range(phi, -1, var, ZEND_LONG_MIN, val, 1, 0, 0);
}
static void pi_type_mask(zend_ssa_phi *phi, uint32_t type_mask) {
phi->constraint.type_mask = MAY_BE_REF|MAY_BE_RC1|MAY_BE_RCN;
phi->constraint.type_mask |= type_mask;
if (type_mask & MAY_BE_NULL) {
phi->constraint.type_mask |= MAY_BE_UNDEF;
}
}
static inline void pi_not_type_mask(zend_ssa_phi *phi, uint32_t type_mask) {
uint32_t relevant = MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
pi_type_mask(phi, ~type_mask & relevant);
}
static inline uint32_t mask_for_type_check(uint32_t type) {
if (type == _IS_BOOL) {
return MAY_BE_TRUE|MAY_BE_FALSE;
} else if (type == IS_ARRAY) {
return MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
} else {
return 1 << type;
}
}
/* We can interpret $a + 5 == 0 as $a = 0 - 5, i.e. shift the adjustment to the other operand.
* This negated adjustment is what is written into the "adjustment" parameter. */
static int find_adjusted_tmp_var(const zend_op_array *op_array, uint32_t build_flags, zend_op *opline, uint32_t var_num, zend_long *adjustment)
@@ -805,6 +828,59 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var))) {
pi_range_not_equals(pi, -1, 0);
}
} else if (opline->op1_type == IS_TMP_VAR && (opline-1)->opcode == ZEND_TYPE_CHECK &&
opline->op1.var == (opline-1)->result.var && (opline-1)->op1_type == IS_CV) {
int var = EX_VAR_TO_NUM((opline-1)->op1.var);
uint32_t type = (opline-1)->extended_value;
if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var))) {
pi_type_mask(pi, mask_for_type_check(type));
}
if (type != IS_OBJECT && type != IS_RESOURCE) {
/* is_object() and is_resource() may return false, even though the value is
* an object/resource. */
if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var))) {
pi_not_type_mask(pi, mask_for_type_check(type));
}
}
} else if (opline->op1_type == IS_TMP_VAR &&
((opline-1)->opcode == ZEND_IS_IDENTICAL
|| (opline-1)->opcode == ZEND_IS_NOT_IDENTICAL) &&
opline->op1.var == (opline-1)->result.var) {
int var;
zval *val;
uint32_t type_mask;
if ((opline-1)->op1_type == IS_CV && (opline-1)->op2_type == IS_CONST) {
var = EX_VAR_TO_NUM((opline-1)->op1.var);
val = CRT_CONSTANT((opline-1)->op2);
} else if ((opline-1)->op1_type == IS_CONST && (opline-1)->op2_type == IS_CV) {
var = EX_VAR_TO_NUM((opline-1)->op2.var);
val = CRT_CONSTANT((opline-1)->op1);
} else {
continue;
}
/* We're interested in === null/true/false comparisons here, because they eliminate
* a type in the false-branch. Other === VAL comparisons are unlikely to be useful. */
if (Z_TYPE_P(val) != IS_NULL && Z_TYPE_P(val) != IS_TRUE && Z_TYPE_P(val) != IS_FALSE) {
continue;
}
type_mask = _const_op_type(val);
if ((opline-1)->opcode == ZEND_IS_IDENTICAL) {
if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var))) {
pi_type_mask(pi, type_mask);
}
if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var))) {
pi_not_type_mask(pi, type_mask);
}
} else {
if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var))) {
pi_type_mask(pi, type_mask);
}
if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var))) {
pi_not_type_mask(pi, type_mask);
}
}
}
}
+4 -3
View File
@@ -38,21 +38,22 @@ typedef enum _zend_ssa_negative_lat {
} zend_ssa_negative_lat;
/* Special kind of SSA Phi function used in eSSA */
typedef struct _zend_ssa_pi_range {
typedef struct _zend_ssa_pi_constraint {
zend_ssa_range range; /* simple range constraint */
int min_var;
int max_var;
int min_ssa_var; /* ((min_var>0) ? MIN(ssa_var) : 0) + range.min */
int max_ssa_var; /* ((man_var>0) ? MAX(ssa_var) : 0) + range.man */
zend_ssa_negative_lat negative;
} zend_ssa_pi_range;
uint32_t type_mask; /* If -1 this is a range constraint */
} zend_ssa_pi_constraint;
/* SSA Phi - ssa_var = Phi(source0, source1, ...sourceN) */
typedef struct _zend_ssa_phi zend_ssa_phi;
struct _zend_ssa_phi {
zend_ssa_phi *next; /* next Phi in the same BB */
int pi; /* if >= 0 this is actually a e-SSA Pi */
zend_ssa_pi_range constraint; /* e-SSA Pi constraint */
zend_ssa_pi_constraint constraint; /* e-SSA Pi constraint */
int var; /* Original CV, VAR or TMP variable index */
int ssa_var; /* SSA variable index */
int block; /* current BB index */
+16
View File
@@ -0,0 +1,16 @@
// $Id$
// vim:ft=javascript
ARG_WITH("readline", "Readline support", "yes");
if (PHP_READLINE != "no") {
if (CHECK_LIB("edit_a.lib;edit.lib", "readline", PHP_READLINE) &&
CHECK_HEADER_ADD_INCLUDE("editline/readline.h", "CFLAGS_READLINE")) {
EXTENSION("readline", "readline.c readline_cli.c");
ADD_FLAG("CFLAGS_READLINE", "/D HAVE_LIBEDIT");
ADD_FLAG("CFLAGS_READLINE", "/D HAVE_RL_COMPLETION_MATCHES");
} else {
WARNING("readline not enabled; libraries and headers not found");
}
}
+2
View File
@@ -22,9 +22,11 @@
#define PHP_READLINE_H
#if HAVE_LIBREADLINE || HAVE_LIBEDIT
#ifndef PHP_WIN32
#ifdef ZTS
#warning Readline module will *NEVER* be thread-safe
#endif
#endif
extern zend_module_entry readline_module_entry;
#define phpext_readline_ptr &readline_module_entry
+8
View File
@@ -251,7 +251,9 @@ PHP_FUNCTION(readline_info)
array_init(return_value);
add_assoc_string(return_value,"line_buffer",SAFE_STRING(rl_line_buffer));
add_assoc_long(return_value,"point",rl_point);
#ifndef PHP_WIN32
add_assoc_long(return_value,"end",rl_end);
#endif
#ifdef HAVE_LIBREADLINE
add_assoc_long(return_value,"mark",rl_mark);
add_assoc_long(return_value,"done",rl_done);
@@ -262,7 +264,9 @@ PHP_FUNCTION(readline_info)
#if HAVE_ERASE_EMPTY_LINE
add_assoc_long(return_value,"erase_empty_line",rl_erase_empty_line);
#endif
#ifndef PHP_WIN32
add_assoc_string(return_value,"library_version",(char *)SAFE_STRING(rl_library_version));
#endif
add_assoc_string(return_value,"readline_name",(char *)SAFE_STRING(rl_readline_name));
add_assoc_long(return_value,"attempted_completion_over",rl_attempted_completion_over);
} else {
@@ -276,8 +280,10 @@ PHP_FUNCTION(readline_info)
RETVAL_STRING(SAFE_STRING(oldstr));
} else if (!strcasecmp(what, "point")) {
RETVAL_LONG(rl_point);
#ifndef PHP_WIN32
} else if (!strcasecmp(what, "end")) {
RETVAL_LONG(rl_end);
#endif
#ifdef HAVE_LIBREADLINE
} else if (!strcasecmp(what, "mark")) {
RETVAL_LONG(rl_mark);
@@ -309,8 +315,10 @@ PHP_FUNCTION(readline_info)
}
RETVAL_LONG(oldval);
#endif
#ifndef PHP_WIN32
} else if (!strcasecmp(what,"library_version")) {
RETVAL_STRING((char *)SAFE_STRING(rl_library_version));
#endif
} else if (!strcasecmp(what, "readline_name")) {
oldstr = (char*)rl_readline_name;
if (value) {
+36 -1
View File
@@ -19,6 +19,10 @@
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#ifndef HAVE_RL_COMPLETION_MATCHES
@@ -63,7 +67,7 @@
#include "sapi/cli/cli.h"
#include "readline_cli.h"
#ifdef COMPILE_DL_READLINE
#if defined(COMPILE_DL_READLINE) && !defined(PHP_WIN32)
#include <dlfcn.h>
#endif
@@ -598,9 +602,15 @@ static int readline_shell_run(void) /* {{{ */
zend_execute_scripts(ZEND_REQUIRE, NULL, 1, prepend_file_p);
}
#ifndef PHP_WIN32
history_file = tilde_expand("~/.php_history");
#else
spprintf(&history_file, MAX_PATH, "%s/.php_history", getenv("USERPROFILE"));
#endif
rl_attempted_completion_function = cli_code_completion;
#ifndef PHP_WIN32
rl_special_prefixes = "$";
#endif
read_history(history_file);
EG(exit_status) = 0;
@@ -686,13 +696,33 @@ static int readline_shell_run(void) /* {{{ */
php_last_char = '\0';
}
#ifdef PHP_WIN32
efree(history_file);
#else
free(history_file);
#endif
efree(code);
zend_string_release(prompt);
return EG(exit_status);
}
/* }}} */
#ifdef PHP_WIN32
typedef cli_shell_callbacks_t *(__cdecl *get_cli_shell_callbacks)(void);
#define GET_SHELL_CB(cb) \
do { \
get_cli_shell_callbacks get_callbacks; \
HMODULE hMod = GetModuleHandle("php.exe"); \
(cb) = NULL; \
if (strlen(sapi_module.name) >= 3 && 0 == strncmp("cli", sapi_module.name, 3)) { \
get_callbacks = (get_cli_shell_callbacks)GetProcAddress(hMod, "php_cli_get_shell_callbacks"); \
if (get_callbacks) { \
(cb) = get_callbacks(); \
} \
} \
} while(0)
#else
/*
#ifdef COMPILE_DL_READLINE
This dlsym() is always used as even the CGI SAPI is linked against "CLI"-only
@@ -711,6 +741,7 @@ this extension sharedto offer compatibility.
/*#else
#define GET_SHELL_CB(cb) (cb) = php_cli_get_shell_callbacks()
#endif*/
#endif
PHP_MINIT_FUNCTION(cli_readline)
{
@@ -755,7 +786,11 @@ PHP_MINFO_FUNCTION(cli_readline)
{
php_info_print_table_start();
php_info_print_table_header(2, "Readline Support", "enabled");
#ifdef PHP_WIN32
php_info_print_table_row(2, "Readline library", "WinEditLine");
#else
php_info_print_table_row(2, "Readline library", (rl_library_version ? rl_library_version : "Unknown"));
#endif
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
@@ -0,0 +1,42 @@
--TEST--
readline_info(): Basic test
--SKIPIF--
<?php if (!extension_loaded("readline")) die("skip");
if (READLINE_LIB != "libedit") die("skip libedit only");
if(substr(PHP_OS, 0, 3) != 'WIN' ) {
die('skip windows only test');
}
?>
--FILE--
<?php
var_dump(readline_info());
var_dump(readline_info(1));
var_dump(readline_info(1,1));
var_dump(readline_info('line_buffer'));
var_dump(readline_info('readline_name'));
var_dump(readline_info('readline_name', 1));
var_dump(readline_info('readline_name'));
var_dump(readline_info('attempted_completion_over',1));
var_dump(readline_info('attempted_completion_over'));
?>
--EXPECTF--
array(4) {
["line_buffer"]=>
string(0) ""
["point"]=>
int(0)
["readline_name"]=>
string(0) ""
["attempted_completion_over"]=>
int(0)
}
NULL
NULL
string(0) ""
string(0) ""
string(0) ""
string(1) "1"
int(0)
int(1)
+3
View File
@@ -3,6 +3,9 @@ readline_info(): Basic test
--SKIPIF--
<?php if (!extension_loaded("readline")) die("skip");
if (READLINE_LIB != "libedit") die("skip libedit only");
if(substr(PHP_OS, 0, 3) == 'WIN' ) {
die('skip not for windows');
}
?>
--FILE--
<?php
@@ -0,0 +1,29 @@
--TEST--
readline_write_history(): Basic test
--SKIPIF--
<?php if (!extension_loaded("readline") || !function_exists('readline_add_history')) die("skip");
if (READLINE_LIB != "libedit") die("skip libedit only");
if(substr(PHP_OS, 0, 3) != 'WIN' ) {
die('skip windows only test');
}
?>
--FILE--
<?php
$name = tempnam(sys_get_temp_dir(), 'readline.tmp');
readline_add_history('foo');
readline_add_history('');
readline_add_history(1);
readline_add_history(NULL);
readline_write_history($name);
var_dump(file_get_contents($name));
unlink($name);
?>
--EXPECT--
string(6) "foo
1
"
@@ -3,6 +3,9 @@ readline_write_history(): Basic test
--SKIPIF--
<?php if (!extension_loaded("readline") || !function_exists('readline_add_history')) die("skip");
if (READLINE_LIB != "libedit") die("skip libedit only");
if(substr(PHP_OS, 0, 3) == 'WIN' ) {
die('skip not for windows');
}
?>
--FILE--
<?php
+10 -1
View File
@@ -85,7 +85,16 @@ PS_OPEN_FUNC(user)
ZVAL_STRING(&args[0], (char*)save_path);
ZVAL_STRING(&args[1], (char*)session_name);
ps_call_handler(&PSF(open), 2, args, &retval);
zend_try {
ps_call_handler(&PSF(open), 2, args, &retval);
} zend_catch {
PS(session_status) = php_session_none;
if (!Z_ISUNDEF(retval)) {
zval_ptr_dtor(&retval);
}
zend_bailout();
} zend_end_try();
PS(mod_user_implemented) = 1;
FINISH;
+25 -2
View File
@@ -22,6 +22,10 @@
#include "php_session.h"
#define PS_SANITY_CHECK \
if (PS(session_status) != php_session_active) { \
php_error_docref(NULL, E_WARNING, "Session is not active"); \
RETURN_FALSE; \
} \
if (PS(default_mod) == NULL) { \
php_error_docref(NULL, E_CORE_ERROR, "Cannot call default session handler"); \
RETURN_FALSE; \
@@ -40,6 +44,7 @@ PHP_METHOD(SessionHandler, open)
{
char *save_path = NULL, *session_name = NULL;
size_t save_path_len, session_name_len;
int ret;
PS_SANITY_CHECK;
@@ -48,7 +53,15 @@ PHP_METHOD(SessionHandler, open)
}
PS(mod_user_is_open) = 1;
RETVAL_BOOL(SUCCESS == PS(default_mod)->s_open(&PS(mod_data), save_path, session_name));
zend_try {
ret = PS(default_mod)->s_open(&PS(mod_data), save_path, session_name);
} zend_catch {
PS(session_status) = php_session_none;
zend_bailout();
} zend_end_try();
RETVAL_BOOL(SUCCESS == ret);
}
/* }}} */
@@ -56,6 +69,8 @@ PHP_METHOD(SessionHandler, open)
Wraps the old close handler */
PHP_METHOD(SessionHandler, close)
{
int ret;
PS_SANITY_CHECK_IS_OPEN;
// don't return on failure, since not closing the default handler
@@ -63,7 +78,15 @@ PHP_METHOD(SessionHandler, close)
zend_parse_parameters_none();
PS(mod_user_is_open) = 0;
RETVAL_BOOL(SUCCESS == PS(default_mod)->s_close(&PS(mod_data)));
zend_try {
ret = PS(default_mod)->s_close(&PS(mod_data));
} zend_catch {
PS(session_status) = php_session_none;
zend_bailout();
} zend_end_try();
RETVAL_BOOL(SUCCESS == ret);
}
/* }}} */
+32 -21
View File
@@ -103,6 +103,7 @@ static void php_session_abort(void);
static inline void php_rinit_session_globals(void) /* {{{ */
{
/* Do NOT init PS(mod_user_names) here! */
/* TODO: These could be moved to MINIT and removed. These should be initialized by php_rshutdown_session_globals() always when execution is finished. */
PS(id) = NULL;
PS(session_status) = php_session_none;
PS(mod_data) = NULL;
@@ -130,10 +131,15 @@ static inline void php_rshutdown_session_globals(void) /* {{{ */
zend_string_release(PS(id));
PS(id) = NULL;
}
if (PS(session_vars)) {
zend_string_release(PS(session_vars));
PS(session_vars) = NULL;
}
/* User save handlers may end up directly here by misuse, bugs in user script, etc. */
/* Set session status to prevent error while restoring save handler INI value. */
PS(session_status) = php_session_none;
}
/* }}} */
@@ -522,7 +528,10 @@ static void php_session_initialize(void) /* {{{ */
}
/* If there is no ID, use session module to create one */
if (!PS(id)) {
if (!PS(id) || !ZSTR_VAL(PS(id))[0]) {
if (PS(id)) {
zend_string_release(PS(id));
}
PS(id) = PS(mod)->s_create_sid(&PS(mod_data));
if (!PS(id)) {
php_session_abort();
@@ -602,11 +611,16 @@ static void php_session_save_current_state(int write) /* {{{ */
}
if ((ret == FAILURE) && !EG(exception)) {
php_error_docref(NULL, E_WARNING, "Failed to write session data (%s). Please "
"verify that the current setting of session.save_path "
"is correct (%s)",
PS(mod)->s_name,
PS(save_path));
if (!PS(mod_user_implemented)) {
php_error_docref(NULL, E_WARNING, "Failed to write session data (%s). Please "
"verify that the current setting of session.save_path "
"is correct (%s)",
PS(mod)->s_name,
PS(save_path));
} else {
php_error_docref(NULL, E_WARNING, "Failed to write session data using user "
"defined save handler. (session.save_path: %s)", PS(save_path));
}
}
}
}
@@ -1107,7 +1121,7 @@ static ps_serializer ps_serializers[MAX_SERIALIZERS + 1] = {
PHPAPI int php_session_register_serializer(const char *name, zend_string *(*encode)(PS_SERIALIZER_ENCODE_ARGS), int (*decode)(PS_SERIALIZER_DECODE_ARGS)) /* {{{ */
{
int ret = -1;
int ret = FAILURE;
int i;
for (i = 0; i < MAX_SERIALIZERS; i++) {
@@ -1116,7 +1130,7 @@ PHPAPI int php_session_register_serializer(const char *name, zend_string *(*enco
ps_serializers[i].encode = encode;
ps_serializers[i].decode = decode;
ps_serializers[i + 1].name = NULL;
ret = 0;
ret = SUCCESS;
break;
}
}
@@ -1138,13 +1152,13 @@ static ps_module *ps_modules[MAX_MODULES + 1] = {
PHPAPI int php_session_register_module(ps_module *ptr) /* {{{ */
{
int ret = -1;
int ret = FAILURE;
int i;
for (i = 0; i < MAX_MODULES; i++) {
if (!ps_modules[i]) {
ps_modules[i] = ptr;
ret = 0;
ret = SUCCESS;
break;
}
}
@@ -1659,8 +1673,8 @@ PHPAPI void php_session_start(void) /* {{{ */
static void php_session_flush(int write) /* {{{ */
{
if (PS(session_status) == php_session_active) {
PS(session_status) = php_session_none;
php_session_save_current_state(write);
PS(session_status) = php_session_none;
}
}
/* }}} */
@@ -1668,10 +1682,10 @@ static void php_session_flush(int write) /* {{{ */
static void php_session_abort(void) /* {{{ */
{
if (PS(session_status) == php_session_active) {
PS(session_status) = php_session_none;
if (PS(mod_data) || PS(mod_user_implemented)) {
PS(mod)->s_close(&PS(mod_data));
}
PS(session_status) = php_session_none;
}
}
/* }}} */
@@ -2046,13 +2060,13 @@ static PHP_FUNCTION(session_regenerate_id)
return;
}
if (SG(headers_sent) && PS(use_cookies)) {
php_error_docref(NULL, E_WARNING, "Cannot regenerate session id - headers already sent");
if (PS(session_status) != php_session_active) {
php_error_docref(NULL, E_WARNING, "Cannot regenerate session id - session is not active");
RETURN_FALSE;
}
if (PS(session_status) != php_session_active) {
php_error_docref(NULL, E_WARNING, "Cannot regenerate session id - session is not active");
if (SG(headers_sent) && PS(use_cookies)) {
php_error_docref(NULL, E_WARNING, "Cannot regenerate session id - headers already sent");
RETURN_FALSE;
}
@@ -2104,6 +2118,7 @@ static PHP_FUNCTION(session_regenerate_id)
zend_string_release(PS(id));
PS(id) = PS(mod)->s_create_sid(&PS(mod_data));
if (!PS(id)) {
PS(mod)->s_close(&PS(mod_data));
PS(session_status) = php_session_none;
php_error_docref(NULL, E_RECOVERABLE_ERROR, "Failed to create session ID by collision: %s (path: %s)", PS(mod)->s_name, PS(save_path));
RETURN_FALSE;
@@ -2111,6 +2126,7 @@ static PHP_FUNCTION(session_regenerate_id)
}
/* Read is required to make new session data at this point. */
if (PS(mod)->s_read(&PS(mod_data), PS(id), &data, PS(gc_maxlifetime)) == FAILURE) {
PS(mod)->s_close(&PS(mod_data));
PS(session_status) = php_session_none;
php_error_docref(NULL, E_RECOVERABLE_ERROR, "Failed to create(read) session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path));
RETURN_FALSE;
@@ -2282,11 +2298,6 @@ static PHP_FUNCTION(session_start)
RETURN_FALSE;
}
if (PS(id) && !(ZSTR_LEN(PS(id)))) {
php_error_docref(NULL, E_WARNING, "Cannot start session with empty session ID");
RETURN_FALSE;
}
/* set options */
if (options) {
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(options), num_idx, str_idx, value) {
+1 -1
View File
@@ -12,4 +12,4 @@ $x = new SessionHandler;
$x->gc(1);
?>
--EXPECTF--
Warning: SessionHandler::gc(): Parent session handler is not open in %s on line %d
Warning: SessionHandler::gc(): Session is not active in %s on line %d
+9
View File
@@ -39,8 +39,17 @@ session_start();
session_write_close();
echo "um, hi\n";
/*
FIXME: Since session module try to write/close session data in
RSHUTDOWN, write() is executed twices. This is caused by undefined
function error and zend_bailout(). Current session module codes
depends on this behavior. These codes should be modified to remove
multiple write().
*/
?>
--EXPECTF--
write: goodbye cruel world
write: goodbye cruel world
close: goodbye cruel world
+6
View File
@@ -41,6 +41,11 @@ session_start();
session_write_close();
echo "um, hi\n";
/*
FIXME: Something wrong. It should try to close after error, otherwise session
may keep "open" state.
*/
?>
--EXPECTF--
write: goodbye cruel world
@@ -51,3 +56,4 @@ Stack trace:
#1 %s(%d): session_write_close()
#2 {main}
thrown in %s on line %d
+2 -1
View File
@@ -7,4 +7,5 @@ Bug #67972: SessionHandler Invalid memory read create_sid()
(new SessionHandler)->create_sid();
--EXPECTF--
Fatal error: SessionHandler::create_sid(): Cannot call default session handler in %s on line %d
Warning: SessionHandler::create_sid(): Session is not active in %s on line %d
+9 -5
View File
@@ -3,18 +3,22 @@ Bug #68063 (Empty session IDs do still start sessions)
--SKIPIF--
<?php include('skipif.inc'); ?>
--INI--
session.use_strict_mode=0
session.hash_function=1
session.hash_bits_per_character=4
--FILE--
<?php
// Empty session ID may happen by browser bugs
// Could also be set with a cookie like "PHPSESSID=; path=/"
session_id('');
// Will still start the session and return true
// Start the session with empty string should result in new session ID
var_dump(session_start());
// Returns an empty string
// Returns newly created session ID
var_dump(session_id());
?>
--EXPECTF--
Warning: session_start(): Cannot start session with empty session ID in %s on line %d
bool(false)
string(0) ""
bool(true)
string(40) "%s"
+36
View File
@@ -0,0 +1,36 @@
--TEST--
Bug #69111 (Crash in SessionHandler::read())
--INI--
session.save_path=
session.save_handler=files
session.name=PHPSESSID
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
<?php
$sh = new SessionHandler;
session_set_save_handler($sh);
$savePath = ini_get('session.save_path');
$sessionName = ini_get('session.name');
// session_start(); // Uncommenting this makes it not crash when reading the session (see below), but it will not return any data.
$sh->open($savePath, $sessionName);
$sh->write("foo", "bar");
$sh->read($id);
$sh->gc(1245);
$sh->close();
?>
--EXPECTF--
Warning: SessionHandler::open(): Session is not active in %s on line 10
Warning: SessionHandler::write(): Session is not active in %s on line 11
Notice: Undefined variable: id in %s on line 12
Warning: SessionHandler::read(): Session is not active in %s on line 12
Warning: SessionHandler::gc(): Session is not active in %s on line 13
Warning: SessionHandler::close(): Session is not active in %s on line 14
+41
View File
@@ -0,0 +1,41 @@
--TEST--
Bug #70133 (Extended SessionHandler::read is ignoring $session_id when calling parent)
--SKIPIF--
<?php include('skipif.inc'); ?>
--INI--
session.save_handler=files
session.save_path=
session.use_strict_mode=0
--FILE--
<?php
class CustomReadHandler extends \SessionHandler {
public function read($session_id) {
return parent::read('mycustomsession');
}
}
ob_start();
session_set_save_handler(new CustomReadHandler(), true);
session_id('mycustomsession');
session_start();
$_SESSION['foo'] = 'hoge';
var_dump(session_id());
session_commit();
session_id('otherid');
session_start();
var_dump($_SESSION);
var_dump(session_id());
?>
--EXPECT--
string(15) "mycustomsession"
array(1) {
["foo"]=>
string(4) "hoge"
}
string(7) "otherid"
@@ -16,4 +16,11 @@ print "Done!\n";
?>
--EXPECTF--
Warning: SessionHandler::open(): Session is not active in %s on line 5
Warning: SessionHandler::open(): Session is not active in %s on line 6
Warning: SessionHandler::open(): Session is not active in %s on line 7
Warning: SessionHandler::open(): Session is not active in %s on line 8
Done!
+1 -1
View File
@@ -2135,7 +2135,7 @@ static void soap_error_handler(int error_num, const char *error_filename, const
_old_http_response_code = SG(sapi_headers).http_response_code;
_old_http_status_line = SG(sapi_headers).http_status_line;
if (!SOAP_GLOBAL(use_soap_error_handler) || !EG(objects_store).object_buckets) {
if (!PG(modules_activated) || !SOAP_GLOBAL(use_soap_error_handler) || !EG(objects_store).object_buckets) {
call_old_error_handler(error_num, error_filename, error_lineno, format, args);
return;
}
@@ -0,0 +1,32 @@
--TEST--
void socket_clear_error ([ resource $socket ] ) ;
--CREDITS--
marcosptf - <marcosptf@yahoo.com.br> - #phparty7 - @phpsp - novatec/2015 - sao paulo - br
--SKIPIF--
<?php
if (!extension_loaded('sockets')) {
die('SKIP sockets extension not available.');
}
if(substr(PHP_OS, 0, 3) != 'WIN' ) {
die('skip windows only test');
}
?>
--FILE--
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$socketConn = socket_connect($socket, "127.0.0.1", 21248);
var_dump(socket_last_error($socket));
socket_clear_error($socket);
var_dump(socket_last_error($socket));
?>
--CLEAN--
<?php
socket_close($socket);
unset($socket);
unset($socketConn);
?>
--EXPECTF--
Warning: socket_connect(): unable to connect [%d]: No connection could be made because the target machine actively refused it.
in %s on line %d
int(%d)
int(%d)
@@ -7,6 +7,9 @@ marcosptf - <marcosptf@yahoo.com.br> - #phparty7 - @phpsp - novatec/2015 - sao p
if (!extension_loaded('sockets')) {
die('SKIP sockets extension not available.');
}
if(substr(PHP_OS, 0, 3) == 'WIN' ) {
die('skip windows only test');
}
?>
--FILE--
<?php
+3
View File
@@ -7,6 +7,9 @@ marcosptf - <marcosptf@yahoo.com.br> - #phparty7 - @phpsp - novatec/2015 - sao p
if (!extension_loaded('sockets')) {
die('SKIP sockets extension not available.');
}
if(substr(PHP_OS, 0, 3) == 'WIN' ) {
die('skip not for windows');
}
?>
--FILE--
<?php
+43
View File
@@ -0,0 +1,43 @@
--TEST--
int socket_send ( resource $socket , string $buf , int $len , int $flags );
--CREDITS--
marcosptf - <marcosptf@yahoo.com.br> - #phparty7 - @phpsp - novatec/2015 - sao paulo - br
--SKIPIF--
<?php
if (!extension_loaded('sockets')) {
die('SKIP sockets extension not available.');
}
if(substr(PHP_OS, 0, 3) != 'WIN' ) {
die('skip windows only test');
}
?>
--FILE--
<?php
$port = 80;
$host = "yahoo.com";
$stringSocket = "send_socket_to_connected_socket";
$stringSocketLenght = strlen($stringSocket);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$socketConn = socket_connect($socket, $host, $port);
if(socket_send($socket, $stringSocket, $stringSocketLenght, MSG_OOB)===$stringSocketLenght){
print("okey\n");
}
if(socket_send($socket, $stringSocket, $stringSocketLenght, MSG_DONTROUTE)===$stringSocketLenght){
print("okey\n");
}
?>
<?php
socket_close($socket);
unset($port);
unset($host);
unset($stringSocket);
unset($stringSocketLenght);
unset($socket);
unset($socketConn);
?>
--EXPECTF--
okey
okey
@@ -0,0 +1,59 @@
--TEST--
bool socket_shutdown ( resource $socket [, int $how = 2 ] ) ;
--CREDITS--
marcosptf - <marcosptf@yahoo.com.br> - #phparty7 - @phpsp - novatec/2015 - sao paulo - br
--SKIPIF--
<?php
if (!extension_loaded('sockets')) {
die('SKIP sockets extension not available.');
}
if(substr(PHP_OS, 0, 3) != 'WIN' ) {
die('skip windows only test');
}
?>
--FILE--
<?php
$host = "yahoo.com";
$port = 80;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$socketConn = socket_connect($socket, $host, $port);
var_dump(socket_shutdown($socket,0));
socket_close($socket);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$socketConn = socket_connect($socket, $host, $port);
var_dump(socket_shutdown($socket,1));
socket_close($socket);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$socketConn = socket_connect($socket, $host, $port);
var_dump(socket_shutdown($socket,2));
socket_close($socket);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
var_dump(socket_shutdown($socket,0));
$socketConn = socket_connect($socket, $host, $port);
var_dump(socket_shutdown($socket,-1));
socket_close($socket);
?>
--CLEAN--
<?php
unset($host);
unset($port);
unset($socket);
unset($socketConn);
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
Warning: socket_shutdown(): unable to shutdown socket [%d]: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied.
in %s on line %d
bool(false)
Warning: socket_shutdown(): unable to shutdown socket [%d]: An invalid argument was supplied.
in %s on line %d
bool(false)
+3
View File
@@ -7,6 +7,9 @@ marcosptf - <marcosptf@yahoo.com.br> - #phparty7 - @phpsp - novatec/2015 - sao p
if (!extension_loaded('sockets')) {
die('SKIP sockets extension not available.');
}
if(substr(PHP_OS, 0, 3) == 'WIN' ) {
die('skip not for windows');
}
?>
--FILE--
<?php
+9 -3
View File
@@ -146,6 +146,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) {
return value;
}
places = places < INT_MIN+1 ? INT_MIN+1 : places;
precision_places = 14 - php_intlog10abs(value);
f1 = php_intpow10(abs(places));
@@ -154,8 +155,10 @@ PHPAPI double _php_math_round(double value, int places, int mode) {
the requested places BUT is small enough to make sure a non-zero value
is returned, pre-round the result to the precision */
if (precision_places > places && precision_places - places < 15) {
f2 = php_intpow10(abs(precision_places));
if (precision_places >= 0) {
int64_t use_precision = precision_places < INT_MIN+1 ? INT_MIN+1 : precision_places;
f2 = php_intpow10(abs((int)use_precision));
if (use_precision >= 0) {
tmp_value = value * f2;
} else {
tmp_value = value / f2;
@@ -163,8 +166,11 @@ PHPAPI double _php_math_round(double value, int places, int mode) {
/* preround the result (tmp_value will always be something * 1e14,
thus never larger than 1e15 here) */
tmp_value = php_round_helper(tmp_value, mode);
use_precision = places - precision_places;
use_precision = use_precision < INT_MIN+1 ? INT_MIN+1 : use_precision;
/* now correctly move the decimal point */
f2 = php_intpow10(abs(places - precision_places));
f2 = php_intpow10(abs((int)use_precision));
/* because places < precision_places */
tmp_value = tmp_value / f2;
} else {
@@ -0,0 +1,69 @@
--TEST--
mixed stream_socket_enable_crypto(resource $stream , bool $enable [, int $crypto_type [, resource $session_stream ]] ) ;
--CREDITS--
marcosptf - <marcosptf@yahoo.com.br> - #phparty7 - @phpsp - novatec/2015 - sao paulo - br
--SKIPIF--
<?php
if (phpversion() < "5.3.0") { die('SKIP php version so lower.'); }
if (!extension_loaded('openssl')) { die('ext/openssl required'); }
if(substr(PHP_OS, 0, 3) != 'WIN' ) {
die('skip windows only test');
}
?>
--FILE--
<?php
$serverUri = "tcp://127.0.0.1:31854";
$sock = stream_socket_server($serverUri, $errno, $errstr);
if (is_resource($sock)) {
var_dump(stream_socket_enable_crypto($sock, false));
var_dump(stream_socket_enable_crypto($sock, true));
var_dump(stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_SSLv2_CLIENT));
var_dump(stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_SSLv3_CLIENT));
var_dump(stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT));
var_dump(stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT));
var_dump(stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_SSLv2_SERVER));
var_dump(stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_SSLv3_SERVER));
var_dump(stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_SSLv23_SERVER));
var_dump(stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_SERVER));
} else {
die("Test stream_socket_enable_crypto has failed; Unable to connect: {$errstr} ({$errno})");
}
?>
--CLEAN--
<?php
unset($serverUri);
unset($sock);
unset($errno);
unset($errstr);
?>
--EXPECTF--
bool(false)
Warning: stream_socket_enable_crypto(): When enabling encryption you must specify the crypto type in %s on line %d
bool(false)
Warning: stream_socket_enable_crypto(): SSLv2 unavailable in the OpenSSL library against which PHP is linked in %s on line %d
bool(false)
Warning: stream_socket_enable_crypto(): SSL: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied.
in %s on line %d
bool(false)
Warning: stream_socket_enable_crypto(): SSL/TLS already set-up for this stream in %s on line %d
bool(false)
Warning: stream_socket_enable_crypto(): SSL/TLS already set-up for this stream in %s on line %d
bool(false)
Warning: stream_socket_enable_crypto(): SSL/TLS already set-up for this stream in %s on line %d
bool(false)
Warning: stream_socket_enable_crypto(): SSL/TLS already set-up for this stream in %s on line %d
bool(false)
Warning: stream_socket_enable_crypto(): SSL/TLS already set-up for this stream in %s on line %d
bool(false)
Warning: stream_socket_enable_crypto(): SSL/TLS already set-up for this stream in %s on line %d
bool(false)
@@ -6,6 +6,9 @@ marcosptf - <marcosptf@yahoo.com.br> - #phparty7 - @phpsp - novatec/2015 - sao p
<?php
if (phpversion() < "5.3.0") { die('SKIP php version so lower.'); }
if (!extension_loaded('openssl')) { die('ext/openssl required'); }
if(substr(PHP_OS, 0, 3) == 'WIN' ) {
die('skip not for windows');
}
?>
--FILE--
<?php
+55 -30
View File
@@ -35,6 +35,7 @@
#ifdef PHP_WIN32
# include "win32/time.h"
# include "win32/signal.h"
# include "win32/winutil.h"
# include <process.h>
#endif
@@ -224,8 +225,10 @@ static php_cgi_globals_struct php_cgi_globals;
#ifdef PHP_WIN32
#define WIN32_MAX_SPAWN_CHILDREN 64
HANDLE win32_kid_cgi_ps[WIN32_MAX_SPAWN_CHILDREN];
int win32_kids;
HANDLE kid_cgi_ps[WIN32_MAX_SPAWN_CHILDREN];
int kids;
HANDLE job = NULL;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = { 0 };
#endif
#ifndef HAVE_ATTRIBUTE_WEAK
@@ -1436,16 +1439,20 @@ void fastcgi_cleanup(int signal)
#else
BOOL fastcgi_cleanup(DWORD sig)
{
int i = win32_kids;
int i = kids;
while (0 < i--) {
if (NULL == win32_kid_cgi_ps[i]) {
if (NULL == kid_cgi_ps[i]) {
continue;
}
TerminateProcess(win32_kid_cgi_ps[i], 0);
CloseHandle(win32_kid_cgi_ps[i]);
win32_kid_cgi_ps[i] = NULL;
TerminateProcess(kid_cgi_ps[i], 0);
CloseHandle(kid_cgi_ps[i]);
kid_cgi_ps[i] = NULL;
}
if (job) {
CloseHandle(job);
}
parent = 0;
@@ -2109,35 +2116,54 @@ consult the installation file that came with this distribution, or visit \n\
char my_name[MAX_PATH] = {0};
int i;
ZeroMemory(&win32_kid_cgi_ps, sizeof(win32_kid_cgi_ps));
win32_kids = children < WIN32_MAX_SPAWN_CHILDREN ? children : WIN32_MAX_SPAWN_CHILDREN;
ZeroMemory(&kid_cgi_ps, sizeof(kid_cgi_ps));
kids = children < WIN32_MAX_SPAWN_CHILDREN ? children : WIN32_MAX_SPAWN_CHILDREN;
SetConsoleCtrlHandler(fastcgi_cleanup, TRUE);
SetEnvironmentVariable("PHP_FCGI_CHILDREN", NULL); /* kids will inherit the env, don't let them spawn */
/* kids will inherit the env, don't let them spawn */
SetEnvironmentVariable("PHP_FCGI_CHILDREN", NULL);
GetModuleFileName(NULL, my_name, MAX_PATH);
cmd_line = my_name;
job = CreateJobObject(NULL, NULL);
if (!job) {
DWORD err = GetLastError();
char *err_text = php_win32_error_to_msg(err);
fprintf(stderr, "unable to create job object: [0x%08lx]: %s\n", err, err_text);
goto parent_out;
}
job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info))) {
DWORD err = GetLastError();
char *err_text = php_win32_error_to_msg(err);
fprintf(stderr, "unable to configure job object: [0x%08lx]: %s\n", err, err_text);
}
while (parent) {
i = win32_kids;
i = kids;
while (0 < i--) {
DWORD status;
if (NULL != win32_kid_cgi_ps[i]) {
if(!GetExitCodeProcess(win32_kid_cgi_ps[i], &status) || status != STILL_ACTIVE) {
CloseHandle(win32_kid_cgi_ps[i]);
win32_kid_cgi_ps[i] = NULL;
if (NULL != kid_cgi_ps[i]) {
if(!GetExitCodeProcess(kid_cgi_ps[i], &status) || status != STILL_ACTIVE) {
CloseHandle(kid_cgi_ps[i]);
kid_cgi_ps[i] = NULL;
}
}
}
i = win32_kids;
i = kids;
while (0 < i--) {
PROCESS_INFORMATION pi;
STARTUPINFO si;
if (NULL != win32_kid_cgi_ps[i]) {
if (NULL != kid_cgi_ps[i]) {
continue;
}
@@ -2151,31 +2177,30 @@ consult the installation file that came with this distribution, or visit \n\
si.hStdError = INVALID_HANDLE_VALUE;
if (CreateProcess(NULL, cmd_line, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
win32_kid_cgi_ps[i] = pi.hProcess;
kid_cgi_ps[i] = pi.hProcess;
if (!AssignProcessToJobObject(job, pi.hProcess)) {
DWORD err = GetLastError();
char *err_text = php_win32_error_to_msg(err);
fprintf(stderr, "unable to assign child process to job object: [0x%08lx]: %s\n", err, err_text);
}
CloseHandle(pi.hThread);
} else {
DWORD err = GetLastError();
char *err_text;
char *err_text = php_win32_error_to_msg(err);
win32_kid_cgi_ps[i] = NULL;
kid_cgi_ps[i] = NULL;
(void)FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
err,
LANG_NEUTRAL,
(LPTSTR)&err_text,
0,
NULL);
fprintf(stderr, "unable to spawn: [0x%08lx]: %s\n", err, err_text);
}
}
WaitForMultipleObjects(win32_kids, win32_kid_cgi_ps, FALSE, INFINITE);
WaitForMultipleObjects(kids, kid_cgi_ps, FALSE, INFINITE);
}
snprintf(kid_buf, 16, "%d", children);
SetEnvironmentVariable("PHP_FCGI_CHILDREN", kid_buf); /* restore my env */
/* restore my env */
SetEnvironmentVariable("PHP_FCGI_CHILDREN", kid_buf);
goto parent_out;
} else {
+5
View File
@@ -12,6 +12,11 @@ if (PHP_CLI == "yes") {
ADD_FLAG("CFLAGS_CLI", "/D PHP_WIN32_DEBUG_HEAP");
}
ADD_FLAG("LDFLAGS_CLI", "/stack:67108864");
if (CHECK_LIB("edit_a.lib;edit.lib", "cli", PHP_CLI) &&
CHECK_HEADER_ADD_INCLUDE("editline/readline.h", "CFLAGS_CLI")) {
ADD_FLAG("CFLAGS_CLI", "/D HAVE_LIBEDIT");
}
}
if (PHP_CLI_WIN32 == "yes") {
@@ -21,7 +21,7 @@ if (shell_exec('PowerShell -Help') === NULL)
// cli_set_process_title(). We're only making the API calls to ensure there are
// no warnings/errors.
$is_windows8 = false;
$is_windows8_or_above = false;
$ps_output = shell_exec("PowerShell -NoProfile \"(Get-Host).UI.RawUI.WindowTitle\"");
if ($ps_output === null)
{
@@ -31,8 +31,8 @@ if ($ps_output === null)
$ps_output = trim($ps_output);
$end_title_windows8 = ": Windows PowerShell";
if (($ps_output == "Windows PowerShell") || (strlen($ps_output) > strlen($end_title_windows8) && substr($ps_output,-strlen($end_title_windows8)) === $end_title_windows8))
$is_windows8 = true;
if (($ps_output == "Windows PowerShell") || (strlen($ps_output) > strlen($end_title_windows8) && substr($ps_output,-strlen($end_title_windows8)) === $end_title_windows8) || PHP_WINDOWS_VERSION_MAJOR >= 10)
$is_windows8_or_above = true;
echo "*** Testing setting the process title ***\n";
@@ -42,7 +42,7 @@ $pid = getmypid();
if (cli_set_process_title($original_title) === true)
echo "Successfully set title\n";
if ($is_windows8)
if ($is_windows8_or_above)
{
$loaded_title = $original_title;
}
@@ -82,4 +82,4 @@ else
*** Testing setting the process title ***
Successfully set title
Successfully verified title using get-process
Successfully verified title using get
Successfully verified title using get
+9
View File
@@ -2645,6 +2645,15 @@ function toolset_setup_common_cflags()
if (VCVERS >= 1900) {
ADD_FLAG('CFLAGS', "/guard:cf");
}
if (VCVERS >= 1800) {
if (PHP_PGI != "yes" && PHP_PGO != "yes") {
ADD_FLAG('CFLAGS', "/Zc:inline");
}
/* We enable /opt:icf only with the debug pack, so /Gw only makes sense there, too. */
if (PHP_DEBUG_PACK == "yes") {
ADD_FLAG('CFLAGS', "/Gw");
}
}
}
} else if (CLANG_TOOLSET) {