static zend_bool is_access_deprecated(const zend_constant *c, const char *access_name) { const char *ns_sep = zend_memrchr(ZSTR_VAL(c->name), '\\', ZSTR_LEN(c->name)); if (ns_sep) { /* Namespaces are always case-insensitive. Only compare shortname. */ size_t shortname_offset = ns_sep - ZSTR_VAL(c->name) + 1; size_t shortname_len = ZSTR_LEN(c->name) - shortname_offset; return memcmp( access_name + shortname_offset, ZSTR_VAL(c->name) + shortname_offset, shortname_len ) != 0; } else { /* No namespace, compare whole name */ return memcmp(access_name, ZSTR_VAL(c->name), ZSTR_LEN(c->name)) != 0; } }
/* {{{ php_url_parse */ PHPAPI php_url *php_url_parse_ex(char const *str, int length) { char port_buf[6]; php_url *ret = ecalloc(1, sizeof(php_url)); char const *s, *e, *p, *pp, *ue; s = str; ue = s + length; /* parse scheme */ if ((e = memchr(s, ':', length)) && (e - s)) { /* validate scheme */ p = s; while (p < e) { /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */ if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') { if (e + 1 < ue) { goto parse_port; } else { goto just_path; } } p++; } if (*(e + 1) == '\0') { /* only scheme is available */ ret->scheme = estrndup(s, (e - s)); php_replace_controlchars_ex(ret->scheme, (e - s)); goto end; } /* * certain schemas like mailto: and zlib: may not have any / after them * this check ensures we support those. */ if (*(e+1) != '/') { /* check if the data we get is a port this allows us to * correctly parse things like a.com:80 */ p = e + 1; while (isdigit(*p)) { p++; } if ((*p == '\0' || *p == '/') && (p - e) < 7) { goto parse_port; } ret->scheme = estrndup(s, (e-s)); php_replace_controlchars_ex(ret->scheme, (e - s)); length -= ++e - s; s = e; goto just_path; } else { ret->scheme = estrndup(s, (e-s)); php_replace_controlchars_ex(ret->scheme, (e - s)); if (*(e+2) == '/') { s = e + 3; if (!strncasecmp("file", ret->scheme, sizeof("file"))) { if (*(e + 3) == '/') { /* support windows drive letters as in: file:///c:/somedir/file.txt */ if (*(e + 5) == ':') { s = e + 4; } goto nohost; } } } else { if (!strncasecmp("file", ret->scheme, sizeof("file"))) { s = e + 1; goto nohost; } else { length -= ++e - s; s = e; goto just_path; } } } } else if (e) { /* no scheme; starts with colon: look for port */ parse_port: p = e + 1; pp = p; while (pp-p < 6 && isdigit(*pp)) { pp++; } if (pp - p > 0 && pp - p < 6 && (*pp == '/' || *pp == '\0')) { long port; memcpy(port_buf, p, (pp - p)); port_buf[pp - p] = '\0'; port = strtol(port_buf, NULL, 10); if (port > 0 && port <= 65535) { ret->port = (unsigned short) port; } else { if (ret->scheme) efree(ret->scheme); efree(ret); return NULL; } } else if (p == pp && *pp == '\0') { if (ret->scheme) efree(ret->scheme); efree(ret); return NULL; } else if (*s == '/' && *(s+1) == '/') { /* relative-scheme URL */ s += 2; } else { goto just_path; } } else if (*s == '/' && *(s+1) == '/') { /* relative-scheme URL */ s += 2; } else { just_path: ue = s + length; goto nohost; } e = ue; if (!(p = memchr(s, '/', (ue - s)))) { char *query, *fragment; query = memchr(s, '?', (ue - s)); fragment = memchr(s, '#', (ue - s)); if (query && fragment) { if (query > fragment) { e = fragment; } else { e = query; } } else if (query) { e = query; } else if (fragment) { e = fragment; } } else { e = p; } /* check for login and password */ if ((p = zend_memrchr(s, '@', (e-s)))) { if ((pp = memchr(s, ':', (p-s)))) { if ((pp-s) > 0) { ret->user = estrndup(s, (pp-s)); php_replace_controlchars_ex(ret->user, (pp - s)); } pp++; if (p-pp > 0) { ret->pass = estrndup(pp, (p-pp)); php_replace_controlchars_ex(ret->pass, (p-pp)); } } else { ret->user = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->user, (p-s)); } s = p + 1; } /* check for port */ if (*s == '[' && *(e-1) == ']') { /* Short circuit portscan, we're dealing with an IPv6 embedded address */ p = s; } else { /* memrchr is a GNU specific extension Emulate for wide compatibility */ for(p = e; p >= s && *p != ':'; p--); } if (p >= s && *p == ':') { if (!ret->port) { p++; if (e-p > 5) { /* port cannot be longer then 5 characters */ if (ret->scheme) efree(ret->scheme); if (ret->user) efree(ret->user); if (ret->pass) efree(ret->pass); efree(ret); return NULL; } else if (e - p > 0) { long port; memcpy(port_buf, p, (e - p)); port_buf[e - p] = '\0'; port = strtol(port_buf, NULL, 10); if (port > 0 && port <= 65535) { ret->port = (unsigned short)port; } else { if (ret->scheme) efree(ret->scheme); if (ret->user) efree(ret->user); if (ret->pass) efree(ret->pass); efree(ret); return NULL; } } p--; } } else { p = e; } /* check if we have a valid host, if we don't reject the string as url */ if ((p-s) < 1) { if (ret->scheme) efree(ret->scheme); if (ret->user) efree(ret->user); if (ret->pass) efree(ret->pass); efree(ret); return NULL; } ret->host = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->host, (p - s)); if (e == ue) { return ret; } s = e; nohost: if ((p = memchr(s, '?', (ue - s)))) { pp = strchr(s, '#'); if (pp && pp < p) { if (pp - s) { ret->path = estrndup(s, (pp-s)); php_replace_controlchars_ex(ret->path, (pp - s)); } p = pp; goto label_parse; } if (p - s) { ret->path = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->path, (p - s)); } if (pp) { if (pp - ++p) { ret->query = estrndup(p, (pp-p)); php_replace_controlchars_ex(ret->query, (pp - p)); } p = pp; goto label_parse; } else if (++p - ue) { ret->query = estrndup(p, (ue-p)); php_replace_controlchars_ex(ret->query, (ue - p)); } } else if ((p = memchr(s, '#', (ue - s)))) { if (p - s) { ret->path = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->path, (p - s)); } label_parse: p++; if (ue - p) { ret->fragment = estrndup(p, (ue-p)); php_replace_controlchars_ex(ret->fragment, (ue - p)); } } else { ret->path = estrndup(s, (ue-s)); php_replace_controlchars_ex(ret->path, (ue - s)); } end: return ret; }
PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, time_t expires, char *path, int path_len, char *domain, int domain_len, int secure, int url_encode, int httponly TSRMLS_DC) { char *cookie, *encoded_value = NULL; int len=sizeof("Set-Cookie: "); char *dt; sapi_header_line ctr = {0}; int result; if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" ); return FAILURE; } if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" ); return FAILURE; } len += name_len; if (value && url_encode) { int encoded_value_len; encoded_value = php_url_encode(value, value_len, &encoded_value_len); len += encoded_value_len; } else if ( value ) { encoded_value = estrdup(value); len += value_len; } if (path) { len += path_len; } if (domain) { len += domain_len; } cookie = emalloc(len + 100); if (value && value_len == 0) { /* * MSIE doesn't delete a cookie when you set it to a null value * so in order to force cookies to be deleted, even on MSIE, we * pick an expiry date in the past */ dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC); snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt); efree(dt); } else { snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : ""); if (expires > 0) { const char *p; strlcat(cookie, "; expires=", len + 100); dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC); /* check to make sure that the year does not exceed 4 digits in length */ p = zend_memrchr(dt, '-', strlen(dt)); if (!p || *(p + 5) != ' ') { efree(dt); efree(cookie); efree(encoded_value); zend_error(E_WARNING, "Expiry date cannot have a year greater then 9999"); return FAILURE; } strlcat(cookie, dt, len + 100); efree(dt); } } if (encoded_value) { efree(encoded_value); } if (path && path_len > 0) { strlcat(cookie, "; path=", len + 100); strlcat(cookie, path, len + 100); } if (domain && domain_len > 0) { strlcat(cookie, "; domain=", len + 100); strlcat(cookie, domain, len + 100); } if (secure) { strlcat(cookie, "; secure", len + 100); } if (httponly) { strlcat(cookie, "; httponly", len + 100); } ctr.line = cookie; ctr.line_len = strlen(cookie); result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC); efree(cookie); return result; }
/* {{{ php_url_parse */ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) { char port_buf[6]; php_url *ret = ecalloc(1, sizeof(php_url)); char const *s, *e, *p, *pp, *ue; s = str; ue = s + length; /* parse scheme */ if ((e = memchr(s, ':', length)) && e != s) { /* validate scheme */ p = s; while (p < e) { /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */ if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') { if (e + 1 < ue && e < s + strcspn(s, "?#")) { goto parse_port; } else { goto just_path; } } p++; } if (e + 1 == ue) { /* only scheme is available */ ret->scheme = estrndup(s, (e - s)); php_replace_controlchars_ex(ret->scheme, (e - s)); return ret; } /* * certain schemas like mailto: and zlib: may not have any / after them * this check ensures we support those. */ if (*(e+1) != '/') { /* check if the data we get is a port this allows us to * correctly parse things like a.com:80 */ p = e + 1; while (p < ue && isdigit(*p)) { p++; } if ((p == ue || *p == '/') && (p - e) < 7) { goto parse_port; } ret->scheme = estrndup(s, (e-s)); php_replace_controlchars_ex(ret->scheme, (e - s)); s = e + 1; goto just_path; } else { ret->scheme = estrndup(s, (e-s)); php_replace_controlchars_ex(ret->scheme, (e - s)); if (e + 2 < ue && *(e + 2) == '/') { s = e + 3; if (!strncasecmp("file", ret->scheme, sizeof("file"))) { if (e + 3 < ue && *(e + 3) == '/') { /* support windows drive letters as in: file:///c:/somedir/file.txt */ if (e + 5 < ue && *(e + 5) == ':') { s = e + 4; } goto just_path; } } } else { s = e + 1; goto just_path; } } } else if (e) { /* no scheme; starts with colon: look for port */ parse_port: p = e + 1; pp = p; while (pp < ue && pp - p < 6 && isdigit(*pp)) { pp++; } if (pp - p > 0 && pp - p < 6 && (pp == ue || *pp == '/')) { zend_long port; memcpy(port_buf, p, (pp - p)); port_buf[pp - p] = '\0'; port = ZEND_STRTOL(port_buf, NULL, 10); if (port > 0 && port <= 65535) { ret->port = (unsigned short) port; if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ s += 2; } } else { if (ret->scheme) efree(ret->scheme); efree(ret); return NULL; } } else if (p == pp && pp == ue) { if (ret->scheme) efree(ret->scheme); efree(ret); return NULL; } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ s += 2; } else { goto just_path; } } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ s += 2; } else { goto just_path; } /* Binary-safe strcspn(s, "/?#") */ e = ue; if ((p = memchr(s, '/', e - s))) { e = p; } if ((p = memchr(s, '?', e - s))) { e = p; } if ((p = memchr(s, '#', e - s))) { e = p; } /* check for login and password */ if ((p = zend_memrchr(s, '@', (e-s)))) { if ((pp = memchr(s, ':', (p-s)))) { ret->user = estrndup(s, (pp-s)); php_replace_controlchars_ex(ret->user, (pp - s)); pp++; ret->pass = estrndup(pp, (p-pp)); php_replace_controlchars_ex(ret->pass, (p-pp)); } else { ret->user = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->user, (p-s)); } s = p + 1; } /* check for port */ if (s < ue && *s == '[' && *(e-1) == ']') { /* Short circuit portscan, we're dealing with an IPv6 embedded address */ p = NULL; } else { p = zend_memrchr(s, ':', (e-s)); } if (p) { if (!ret->port) { p++; if (e-p > 5) { /* port cannot be longer then 5 characters */ if (ret->scheme) efree(ret->scheme); if (ret->user) efree(ret->user); if (ret->pass) efree(ret->pass); efree(ret); return NULL; } else if (e - p > 0) { zend_long port; memcpy(port_buf, p, (e - p)); port_buf[e - p] = '\0'; port = ZEND_STRTOL(port_buf, NULL, 10); if (port > 0 && port <= 65535) { ret->port = (unsigned short)port; } else { if (ret->scheme) efree(ret->scheme); if (ret->user) efree(ret->user); if (ret->pass) efree(ret->pass); efree(ret); return NULL; } } p--; } } else { p = e; } /* check if we have a valid host, if we don't reject the string as url */ if ((p-s) < 1) { if (ret->scheme) efree(ret->scheme); if (ret->user) efree(ret->user); if (ret->pass) efree(ret->pass); efree(ret); return NULL; } ret->host = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->host, (p - s)); if (e == ue) { return ret; } s = e; just_path: e = ue; p = memchr(s, '#', (e - s)); if (p) { p++; if (p < e) { ret->fragment = estrndup(p, (e - p)); php_replace_controlchars_ex(ret->fragment, (e - p)); } e = p-1; } p = memchr(s, '?', (e - s)); if (p) { p++; if (p < e) { ret->query = estrndup(p, (e - p)); php_replace_controlchars_ex(ret->query, (e - p)); } e = p-1; } if (s < e || s == ue) { ret->path = estrndup(s, (e - s)); php_replace_controlchars_ex(ret->path, (e - s)); } return ret; }
ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, zend_ulong flags) { zend_constant *c; const char *colon; zend_class_entry *ce = NULL; zend_string *class_name; const char *name = cname->val; size_t name_len = cname->len; /* Skip leading \\ */ if (name[0] == '\\') { name += 1; name_len -= 1; cname = NULL; } if ((colon = zend_memrchr(name, ':', name_len)) && colon > name && (*(colon - 1) == ':')) { int class_name_len = colon - name - 1; size_t const_name_len = name_len - class_name_len - 2; zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0); char *lcname; zval *ret_constant = NULL; ALLOCA_FLAG(use_heap) class_name = zend_string_init(name, class_name_len, 0); lcname = do_alloca(class_name_len + 1, use_heap); zend_str_tolower_copy(lcname, name, class_name_len); if (!scope) { if (EG(current_execute_data)) { scope = EG(scope); } else { scope = CG(active_class_entry); } } if (class_name_len == sizeof("self")-1 && !memcmp(lcname, "self", sizeof("self")-1)) { if (UNEXPECTED(!scope)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot access self:: when no class scope is active"); return NULL; } ce = scope; } else if (class_name_len == sizeof("parent")-1 && !memcmp(lcname, "parent", sizeof("parent")-1)) { if (UNEXPECTED(!scope)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot access parent:: when no class scope is active"); return NULL; } else if (UNEXPECTED(!scope->parent)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot access parent:: when current class scope has no parent"); return NULL; } else { ce = scope->parent; } } else if (class_name_len == sizeof("static")-1 && !memcmp(lcname, "static", sizeof("static")-1)) { ce = zend_get_called_scope(EG(current_execute_data)); if (UNEXPECTED(!ce)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot access static:: when no class scope is active"); return NULL; } } else { ce = zend_fetch_class(class_name, flags); } free_alloca(lcname, use_heap); if (ce) { ret_constant = zend_hash_find(&ce->constants_table, constant_name); if (ret_constant == NULL) { if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) { zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s::%s'", class_name->val, constant_name->val); zend_string_release(class_name); zend_string_free(constant_name); return NULL; } } else if (Z_ISREF_P(ret_constant)) { ret_constant = Z_REFVAL_P(ret_constant); } } zend_string_release(class_name); zend_string_free(constant_name); if (ret_constant && Z_CONSTANT_P(ret_constant)) { if (UNEXPECTED(zval_update_constant_ex(ret_constant, 1, ce) != SUCCESS)) { return NULL; } } return ret_constant; } /* non-class constant */ if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) { /* compound constant name */ int prefix_len = colon - name; size_t const_name_len = name_len - prefix_len - 1; const char *constant_name = colon + 1; char *lcname; size_t lcname_len; ALLOCA_FLAG(use_heap) lcname_len = prefix_len + 1 + const_name_len; lcname = do_alloca(lcname_len + 1, use_heap); zend_str_tolower_copy(lcname, name, prefix_len); /* Check for namespace constant */ lcname[prefix_len] = '\\'; memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1); if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) == NULL) { /* try lowercase */ zend_str_tolower(lcname + prefix_len + 1, const_name_len); if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) != NULL) { if ((c->flags & CONST_CS) != 0) { c = NULL; } } } free_alloca(lcname, use_heap); if (c) { return &c->value; } /* name requires runtime resolution, need to check non-namespaced name */ if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) { return zend_get_constant_str(constant_name, const_name_len); } return NULL; } if (cname) { return zend_get_constant(cname); } else { return zend_get_constant_str(name, name_len); } }
ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags) { zend_constant *c; const char *colon; zend_class_entry *ce = NULL; const char *name = ZSTR_VAL(cname); size_t name_len = ZSTR_LEN(cname); /* Skip leading \\ */ if (name[0] == '\\') { name += 1; name_len -= 1; cname = NULL; } if ((colon = zend_memrchr(name, ':', name_len)) && colon > name && (*(colon - 1) == ':')) { int class_name_len = colon - name - 1; size_t const_name_len = name_len - class_name_len - 2; zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0); zend_string *class_name = zend_string_init(name, class_name_len, 0); zval *ret_constant = NULL; if (zend_string_equals_literal_ci(class_name, "self")) { if (UNEXPECTED(!scope)) { zend_throw_error(NULL, "Cannot access self:: when no class scope is active"); goto failure; } ce = scope; } else if (zend_string_equals_literal_ci(class_name, "parent")) { if (UNEXPECTED(!scope)) { zend_throw_error(NULL, "Cannot access parent:: when no class scope is active"); goto failure; } else if (UNEXPECTED(!scope->parent)) { zend_throw_error(NULL, "Cannot access parent:: when current class scope has no parent"); goto failure; } else { ce = scope->parent; } } else if (zend_string_equals_literal_ci(class_name, "static")) { ce = zend_get_called_scope(EG(current_execute_data)); if (UNEXPECTED(!ce)) { zend_throw_error(NULL, "Cannot access static:: when no class scope is active"); goto failure; } } else { ce = zend_fetch_class(class_name, flags); } if (ce) { zend_class_constant *c = zend_hash_find_ptr(&ce->constants_table, constant_name); if (c == NULL) { if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) { zend_throw_error(NULL, "Undefined class constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); goto failure; } ret_constant = NULL; } else { if (!zend_verify_const_access(c, scope)) { zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); goto failure; } ret_constant = &c->value; } } if (ret_constant && Z_CONSTANT_P(ret_constant)) { if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) { if (IS_CONSTANT_VISITED(ret_constant)) { zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); ret_constant = NULL; goto failure; } MARK_CONSTANT_VISITED(ret_constant); } if (UNEXPECTED(zval_update_constant_ex(ret_constant, ce) != SUCCESS)) { RESET_CONSTANT_VISITED(ret_constant); ret_constant = NULL; goto failure; } RESET_CONSTANT_VISITED(ret_constant); } failure: zend_string_release(class_name); zend_string_free(constant_name); return ret_constant; } /* non-class constant */ if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) { /* compound constant name */ int prefix_len = colon - name; size_t const_name_len = name_len - prefix_len - 1; const char *constant_name = colon + 1; char *lcname; size_t lcname_len; ALLOCA_FLAG(use_heap) lcname_len = prefix_len + 1 + const_name_len; lcname = do_alloca(lcname_len + 1, use_heap); zend_str_tolower_copy(lcname, name, prefix_len); /* Check for namespace constant */ lcname[prefix_len] = '\\'; memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1); if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) == NULL) { /* try lowercase */ zend_str_tolower(lcname + prefix_len + 1, const_name_len); if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) != NULL) { if ((c->flags & CONST_CS) != 0) { c = NULL; } } } free_alloca(lcname, use_heap); if (c) { return &c->value; } /* name requires runtime resolution, need to check non-namespaced name */ if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) { return zend_get_constant_str(constant_name, const_name_len); } return NULL; } if (cname) { return zend_get_constant(cname); } else { return zend_get_constant_str(name, name_len); } }
PHPAPI int php_setcookie(char *name, size_t name_len, char *value, size_t value_len, time_t expires, char *path, size_t path_len, char *domain, size_t domain_len, int secure, int url_encode, int httponly TSRMLS_DC) { char *cookie; size_t len=sizeof("Set-Cookie: "); zend_string *dt; sapi_header_line ctr = {0}; int result; zend_string *encoded_value = NULL; if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" ); return FAILURE; } if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" ); return FAILURE; } len += name_len; if (value && url_encode) { encoded_value = php_url_encode(value, value_len); len += encoded_value->len; } else if (value) { encoded_value = zend_string_init(value, value_len, 0); len += encoded_value->len; } if (path) { len += path_len; } if (domain) { len += domain_len; } cookie = emalloc(len + 100); if (value && value_len == 0) { /* * MSIE doesn't delete a cookie when you set it to a null value * so in order to force cookies to be deleted, even on MSIE, we * pick an expiry date in the past */ dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC); snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s; Max-Age=0", name, dt->val); zend_string_free(dt); } else { snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value->val : ""); if (expires > 0) { const char *p; char tsdelta[13]; strlcat(cookie, COOKIE_EXPIRES, len + 100); dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC); /* check to make sure that the year does not exceed 4 digits in length */ p = zend_memrchr(dt->val, '-', dt->len); if (!p || *(p + 5) != ' ') { zend_string_free(dt); efree(cookie); zend_string_free(encoded_value); zend_error(E_WARNING, "Expiry date cannot have a year greater than 9999"); return FAILURE; } strlcat(cookie, dt->val, len + 100); zend_string_free(dt); snprintf(tsdelta, sizeof(tsdelta), ZEND_LONG_FMT, (zend_long) difftime(expires, time(NULL))); strlcat(cookie, COOKIE_MAX_AGE, len + 100); strlcat(cookie, tsdelta, len + 100); } } if (encoded_value) { zend_string_free(encoded_value); } if (path && path_len > 0) { strlcat(cookie, COOKIE_PATH, len + 100); strlcat(cookie, path, len + 100); } if (domain && domain_len > 0) { strlcat(cookie, COOKIE_DOMAIN, len + 100); strlcat(cookie, domain, len + 100); } if (secure) { strlcat(cookie, COOKIE_SECURE, len + 100); } if (httponly) { strlcat(cookie, COOKIE_HTTPONLY, len + 100); } ctr.line = cookie; ctr.line_len = (uint)strlen(cookie); result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC); efree(cookie); return result; }
int zend_optimizer_update_op2_const(zend_op_array *op_array, zend_op *opline, zval *val) { switch (opline->opcode) { case ZEND_ASSIGN_REF: zval_dtor(val); return 0; case ZEND_FETCH_CLASS: case ZEND_INIT_FCALL_BY_NAME: /*case ZEND_INIT_NS_FCALL_BY_NAME:*/ case ZEND_ADD_INTERFACE: case ZEND_ADD_TRAIT: case ZEND_INSTANCEOF: case ZEND_FETCH_STATIC_PROP_R: case ZEND_FETCH_STATIC_PROP_W: case ZEND_FETCH_STATIC_PROP_RW: case ZEND_FETCH_STATIC_PROP_IS: case ZEND_FETCH_STATIC_PROP_UNSET: case ZEND_FETCH_STATIC_PROP_FUNC_ARG: case ZEND_UNSET_STATIC_PROP: case ZEND_ISSET_ISEMPTY_STATIC_PROP: REQUIRES_STRING(val); drop_leading_backslash(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); alloc_cache_slots_op2(op_array, opline, 1); break; case ZEND_INIT_FCALL: REQUIRES_STRING(val); zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); opline->op2.constant = zend_optimizer_add_literal(op_array, val); alloc_cache_slots_op2(op_array, opline, 1); break; case ZEND_INIT_DYNAMIC_CALL: if (Z_TYPE_P(val) == IS_STRING) { if (zend_memrchr(Z_STRVAL_P(val), ':', Z_STRLEN_P(val))) { zval_dtor(val); return 0; } opline->opcode = ZEND_INIT_FCALL_BY_NAME; drop_leading_backslash(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); alloc_cache_slots_op2(op_array, opline, 1); } else { opline->op2.constant = zend_optimizer_add_literal(op_array, val); } break; case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: REQUIRES_STRING(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); alloc_cache_slots_op2(op_array, opline, 2); break; /*case ZEND_FETCH_CLASS_CONSTANT:*/ case ZEND_ASSIGN_OBJ: case ZEND_FETCH_OBJ_R: case ZEND_FETCH_OBJ_W: case ZEND_FETCH_OBJ_RW: case ZEND_FETCH_OBJ_IS: case ZEND_FETCH_OBJ_UNSET: case ZEND_FETCH_OBJ_FUNC_ARG: case ZEND_UNSET_OBJ: case ZEND_PRE_INC_OBJ: case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: case ZEND_ISSET_ISEMPTY_PROP_OBJ: TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); alloc_cache_slots_op2(op_array, opline, 2); break; case ZEND_ASSIGN_ADD: case ZEND_ASSIGN_SUB: case ZEND_ASSIGN_MUL: case ZEND_ASSIGN_DIV: case ZEND_ASSIGN_POW: case ZEND_ASSIGN_MOD: case ZEND_ASSIGN_SL: case ZEND_ASSIGN_SR: case ZEND_ASSIGN_CONCAT: case ZEND_ASSIGN_BW_OR: case ZEND_ASSIGN_BW_AND: case ZEND_ASSIGN_BW_XOR: if (opline->extended_value == ZEND_ASSIGN_OBJ) { TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); alloc_cache_slots_op2(op_array, opline, 2); } else { opline->op2.constant = zend_optimizer_add_literal(op_array, val); } break; case ZEND_OP_DATA: if ((opline-1)->opcode != ZEND_ASSIGN_DIM && ((opline-1)->extended_value != ZEND_ASSIGN_DIM || ((opline-1)->opcode != ZEND_ASSIGN_ADD && (opline-1)->opcode != ZEND_ASSIGN_SUB && (opline-1)->opcode != ZEND_ASSIGN_MUL && (opline-1)->opcode != ZEND_ASSIGN_DIV && (opline-1)->opcode != ZEND_ASSIGN_POW && (opline-1)->opcode != ZEND_ASSIGN_MOD && (opline-1)->opcode != ZEND_ASSIGN_SL && (opline-1)->opcode != ZEND_ASSIGN_SR && (opline-1)->opcode != ZEND_ASSIGN_CONCAT && (opline-1)->opcode != ZEND_ASSIGN_BW_OR && (opline-1)->opcode != ZEND_ASSIGN_BW_AND && (opline-1)->opcode != ZEND_ASSIGN_BW_XOR)) ) { opline->op2.constant = zend_optimizer_add_literal(op_array, val); break; } /* break missing intentionally */ case ZEND_ISSET_ISEMPTY_DIM_OBJ: case ZEND_ADD_ARRAY_ELEMENT: case ZEND_INIT_ARRAY: case ZEND_ASSIGN_DIM: case ZEND_UNSET_DIM: case ZEND_FETCH_DIM_R: case ZEND_FETCH_DIM_W: case ZEND_FETCH_DIM_RW: case ZEND_FETCH_DIM_IS: case ZEND_FETCH_DIM_FUNC_ARG: case ZEND_FETCH_DIM_UNSET: case ZEND_FETCH_LIST: if (Z_TYPE_P(val) == IS_STRING) { zend_ulong index; if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) { zval_dtor(val); ZVAL_LONG(val, index); } } opline->op2.constant = zend_optimizer_add_literal(op_array, val); break; case ZEND_ROPE_INIT: case ZEND_ROPE_ADD: case ZEND_ROPE_END: case ZEND_CONCAT: case ZEND_FAST_CONCAT: TO_STRING_NOWARN(val); /* break missing intentionally */ default: opline->op2.constant = zend_optimizer_add_literal(op_array, val); break; } ZEND_OP2_TYPE(opline) = IS_CONST; if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline))); } return 1; }