static int php_password_salt_to64(const char *str, const size_t str_len, const size_t out_len, char *ret) /* {{{ */ { size_t pos = 0; zend_string *buffer; if ((int) str_len < 0) { return FAILURE; } buffer = php_base64_encode((unsigned char*) str, str_len); if (ZSTR_LEN(buffer) < out_len) { /* Too short of an encoded string generated */ zend_string_release(buffer); return FAILURE; } for (pos = 0; pos < out_len; pos++) { if (ZSTR_VAL(buffer)[pos] == '+') { ret[pos] = '.'; } else if (ZSTR_VAL(buffer)[pos] == '=') { zend_string_free(buffer); return FAILURE; } else { ret[pos] = ZSTR_VAL(buffer)[pos]; } } zend_string_free(buffer); return SUCCESS; }
/** * Gets the global zval into PG macro */ int zephir_get_global(zval *arr, const char *global, unsigned int global_length) { zval *gv; zend_bool jit_initialization = PG(auto_globals_jit); zend_string *str = zend_string_init(global, global_length, 0); if (jit_initialization) { zend_is_auto_global(str); } zval_ptr_dtor(arr); ZVAL_UNDEF(arr); if (&EG(symbol_table)) { if ((gv = zend_hash_find(&EG(symbol_table), str)) != NULL) { if (Z_TYPE_P(gv) == IS_ARRAY) { ZVAL_COPY_VALUE(arr, gv); zend_string_free(str); return SUCCESS; } } } array_init(arr); zend_hash_update(&EG(symbol_table), str, arr); zend_string_free(str); return SUCCESS; }
/* {{{ php_zlib_encode() */ static zend_string *php_zlib_encode(const char *in_buf, size_t in_len, int encoding, int level) { int status; z_stream Z; zend_string *out; memset(&Z, 0, sizeof(z_stream)); Z.zalloc = php_zlib_alloc; Z.zfree = php_zlib_free; if (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, encoding, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) { out = zend_string_alloc(PHP_ZLIB_BUFFER_SIZE_GUESS(in_len), 0); Z.next_in = (Bytef *) in_buf; Z.next_out = (Bytef *) ZSTR_VAL(out); Z.avail_in = in_len; Z.avail_out = ZSTR_LEN(out); status = deflate(&Z, Z_FINISH); deflateEnd(&Z); if (Z_STREAM_END == status) { /* size buffer down to actual length */ out = zend_string_truncate(out, Z.total_out, 0); ZSTR_VAL(out)[ZSTR_LEN(out)] = '\0'; return out; } else { zend_string_free(out); } } php_error_docref(NULL, E_WARNING, "%s", zError(status)); return NULL; }
static zend_constant *zend_get_special_constant(const char *name, size_t name_len) { zend_constant *c; static char haltoff[] = "__COMPILER_HALT_OFFSET__"; if (!EG(current_execute_data)) { return NULL; } else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 && !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) { const char *cfilename; zend_string *haltname; size_t clen; cfilename = zend_get_executed_filename(); clen = strlen(cfilename); /* check for __COMPILER_HALT_OFFSET__ */ haltname = zend_mangle_property_name(haltoff, sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0); c = zend_hash_find_ptr(EG(zend_constants), haltname); zend_string_free(haltname); return c; } else { return NULL; } }
/* {{{ clone handler for Transliterator */ static zend_object *Transliterator_clone_obj( zval *object ) { Transliterator_object *to_orig, *to_new; zend_object *ret_val; intl_error_reset( NULL ); to_orig = Z_INTL_TRANSLITERATOR_P( object ); intl_error_reset( INTL_DATA_ERROR_P( to_orig ) ); ret_val = Transliterator_ce_ptr->create_object( Z_OBJCE_P( object ) ); to_new = php_intl_transliterator_fetch_object( ret_val ); zend_objects_clone_members( &to_new->zo, &to_orig->zo ); if( to_orig->utrans != NULL ) { zval tempz; /* dummy zval to pass to transliterator_object_construct */ /* guaranteed to return NULL if it fails */ UTransliterator *utrans = utrans_clone( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to_orig ) ); if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) ) goto err; ZVAL_OBJ(&tempz, ret_val); transliterator_object_construct( &tempz, utrans, TRANSLITERATOR_ERROR_CODE_P( to_orig ) ); if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to_orig ) ) ) { zend_string *err_msg; err: if( utrans != NULL ) transliterator_object_destroy( to_new ); /* set the error anyway, in case in the future we decide not to * throw an error. It also helps build the error message */ intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( to_orig ) ); intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to_orig ), "Could not clone transliterator", 0 ); err_msg = intl_error_get_message( TRANSLITERATOR_ERROR_P( to_orig ) ); zend_throw_error( NULL, "%s", ZSTR_VAL(err_msg) ); zend_string_free( err_msg ); /* if it's changed into a warning */ /* do not destroy tempz; we need to return something */ } } else { /* We shouldn't have unconstructed objects in the first place */ php_error_docref( NULL, E_WARNING, "Cloning unconstructed transliterator." ); } return ret_val; }
static int php_info_print_html_esc(const char *str, size_t len) /* {{{ */ { size_t written; zend_string *new_str; new_str = php_escape_html_entities((unsigned char *) str, len, 0, ENT_QUOTES, "utf-8"); written = php_output_write(ZSTR_VAL(new_str), ZSTR_LEN(new_str)); zend_string_free(new_str); return written; }
static zend_string *unserialize_str(const unsigned char **p, size_t len, size_t maxlen) { size_t i, j; zend_string *str = zend_string_alloc(len, 0); unsigned char *end = *(unsigned char **)p+maxlen; if (end < *p) { zend_string_free(str); return NULL; } for (i = 0; i < len; i++) { if (*p >= end) { zend_string_free(str); return NULL; } if (**p != '\\') { ZSTR_VAL(str)[i] = (char)**p; } else { unsigned char ch = 0; for (j = 0; j < 2; j++) { (*p)++; if (**p >= '0' && **p <= '9') { ch = (ch << 4) + (**p -'0'); } else if (**p >= 'a' && **p <= 'f') { ch = (ch << 4) + (**p -'a'+10); } else if (**p >= 'A' && **p <= 'F') { ch = (ch << 4) + (**p -'A'+10); } else { zend_string_free(str); return NULL; } } ZSTR_VAL(str)[i] = (char)ch; } (*p)++; } ZSTR_VAL(str)[i] = 0; ZSTR_LEN(str) = i; return str; }
static int co_socket_onReadable(swReactor *reactor, swEvent *event) { util_socket *sock = (util_socket *) event->socket->object; php_context *context = &sock->context; zval *retval = NULL; zval result; reactor->del(reactor, sock->fd); if (sock->timer) { swTimer_del(&SwooleG.timer, sock->timer); sock->timer = NULL; } int n = read(sock->fd, sock->buf->val, sock->nbytes); if (n < 0) { ZVAL_FALSE(&result); zend_string_free(sock->buf); } else if (n == 0) { ZVAL_EMPTY_STRING(&result); zend_string_free(sock->buf); } else { sock->buf->val[n] = 0; sock->buf->len = n; ZVAL_STR(&result, sock->buf); } int ret = coro_resume(context, &result, &retval); zval_ptr_dtor(&result); if (ret == CORO_END && retval) { zval_ptr_dtor(retval); } efree(sock); return SW_OK; }
static int php_info_print_html_esc(const char *str, size_t len) /* {{{ */ { size_t written; zend_string *new_str; TSRMLS_FETCH(); new_str = php_escape_html_entities((unsigned char *) str, len, 0, ENT_QUOTES, "utf-8" TSRMLS_CC); written = php_output_write(new_str->val, new_str->len TSRMLS_CC); zend_string_free(new_str); return written; }
void ds_throw_exception(zend_class_entry *ce, const char *format, ...) { va_list ap; zend_string *str; va_start(ap, format); str = vstrpprintf(0, format, ap); va_end(ap); zend_throw_exception(ce, str->val, 0); zend_string_free(str); }
void stream_client_do_connect_blocking( skyray_stream_client_t *self, zend_object *protocol_obj, zend_string *host, zend_long port, zval *return_value) { int fd = stream_client_do_connect(host->val, port); if (fd < 0) { return; } zval zstream; object_init_ex(&zstream, skyray_ce_Stream); zend_object *stream = Z_OBJ_P(&zstream); skyray_stream_t * stream_intern = skyray_stream_from_obj(stream); skyray_stream_init_blocking(stream_intern, SR_TCP, fd, protocol_obj); skyray_stream_on_opened(stream_intern, SR_READABLE | SR_WRITABLE); if (!self->protocol_creator) { ZVAL_COPY(return_value, &zstream); return; } zend_string *buffer; ++GC_REFCOUNT(protocol_obj); //preventing protocol instance be free'd after connection closed. while((buffer = skyray_stream_read(stream_intern, 0))) { if (buffer->len == 0) { zend_string_free(buffer); break; } skyray_stream_on_data(stream_intern, buffer); zend_string_free(buffer); } RETURN_OBJ(protocol_obj); }
PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen, int encode) { char *result; smart_str surl = {0}; smart_str buf = {0}; smart_str url_app = {0}; zend_string *encoded; smart_str_appendl(&surl, url, urllen); if (encode) { encoded = php_raw_url_encode(name, strlen(name)); smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); } else { smart_str_appends(&url_app, name); } smart_str_appendc(&url_app, '='); if (encode) { encoded = php_raw_url_encode(value, strlen(value)); smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); } else { smart_str_appends(&url_app, value); } append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output); smart_str_0(&buf); if (newlen) *newlen = ZSTR_LEN(buf.s); result = estrndup(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s)); smart_str_free(&url_app); smart_str_free(&buf); return result; }
void smart_str_appendz(smart_str *buffer, zval *value) { switch (Z_TYPE_P(value)) { case IS_STRING: smart_str_append(buffer, Z_STR_P(value)); return; case IS_LONG: smart_str_append_long(buffer, Z_LVAL_P(value)); return; } zend_string *str = zval_get_string(value); smart_str_append(buffer, str); zend_string_free(str); }
/* This function is meant to unify the headers passed to to mail() * This means, use PCRE to transform single occurrences of \n or \r in \r\n * As a second step we also eleminate all \r\n occurrences which are: * 1) At the start of the header * 2) At the end of the header * 3) Two or more occurrences in the header are removed so only one is left * * Returns NULL on error, or the new char* buffer on success. * You have to take care and efree() the buffer on your own. */ static zend_string *php_win32_mail_trim_header(char *header) { #if HAVE_PCRE || HAVE_BUNDLED_PCRE zend_string *result, *result2; zval replace; zend_string *regex; if (!header) { return NULL; } ZVAL_STRINGL(&replace, PHP_WIN32_MAIL_UNIFY_REPLACE, strlen(PHP_WIN32_MAIL_UNIFY_REPLACE)); regex = zend_string_init(PHP_WIN32_MAIL_UNIFY_REPLACE, sizeof(PHP_WIN32_MAIL_UNIFY_REPLACE)-1, 0); //zend_string *php_pcre_replace(zend_string *regex, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int limit, int *replace_count); result = php_pcre_replace(regex, header, (int)strlen(header), &replace, 0, -1, NULL); if (NULL == result) { zval_ptr_dtor(&replace); zend_string_free(regex); return NULL; } ZVAL_STRING(&replace, PHP_WIN32_MAIL_RMVDBL_PATTERN); regex = zend_string_init(PHP_WIN32_MAIL_RMVDBL_PATTERN, sizeof(PHP_WIN32_MAIL_RMVDBL_PATTERN)-1, 0); result2 = php_pcre_replace(regex, result->val, (int)result->len, &replace, 0, -1, NULL); return result; #else /* In case we don't have PCRE support (for whatever reason...) simply do nothing and return the unmodified header */ return estrdup(header); #endif }
zend_string * ion_buffer_read_all(ion_buffer * buffer) { size_t incoming_length = evbuffer_get_length(bufferevent_get_input(buffer)); zend_string * data; if(!incoming_length) { return ZSTR_EMPTY_ALLOC(); } data = zend_string_alloc(incoming_length, 0); ZSTR_LEN(data) = bufferevent_read(buffer, ZSTR_VAL(data), incoming_length); if (ZSTR_LEN(data) > 0) { ZSTR_VAL(data)[ZSTR_LEN(data)] = '\0'; return data; } else { zend_string_free(data); return NULL; } }
static zend_class_entry * spl_find_ce_by_name(zend_string *name, zend_bool autoload) { zend_class_entry *ce; if (!autoload) { zend_string *lc_name = zend_string_tolower(name); ce = zend_hash_find_ptr(EG(class_table), lc_name); zend_string_free(lc_name); } else { ce = zend_lookup_class(name); } if (ce == NULL) { php_error_docref(NULL, E_WARNING, "Class %s does not exist%s", ZSTR_VAL(name), autoload ? " and could not be loaded" : ""); return NULL; } return ce; }
void skyray_http_request_resolve_queries_if_needed(skyray_http_request_t *self) { if (!ZVAL_IS_NULL(&self->query_params) || ZVAL_IS_NULL(&self->uri)) { return; } array_init(&self->query_params); php_url *url = php_url_parse_ex(Z_STR(self->uri)->val, Z_STR(self->uri)->len); if (!url->query) { php_url_free(url); return; } zend_string *query = zend_string_init(url->query, strlen(url->query), 0); char *res = estrdup(url->query); sapi_module.treat_data(PARSE_STRING, res, &self->query_params); zend_string_free(query); php_url_free(url); }
/* {{{ clone handler for TimeZone */ static zend_object *TimeZone_clone_obj(zval *object) { TimeZone_object *to_orig, *to_new; zend_object *ret_val; intl_error_reset(NULL); to_orig = Z_INTL_TIMEZONE_P(object); intl_error_reset(TIMEZONE_ERROR_P(to_orig)); ret_val = TimeZone_ce_ptr->create_object(Z_OBJCE_P(object)); to_new = php_intl_timezone_fetch_object(ret_val); zend_objects_clone_members(&to_new->zo, &to_orig->zo); if (to_orig->utimezone != NULL) { TimeZone *newTimeZone; newTimeZone = to_orig->utimezone->clone(); to_new->should_delete = 1; if (!newTimeZone) { zend_string *err_msg; intl_errors_set_code(TIMEZONE_ERROR_P(to_orig), U_MEMORY_ALLOCATION_ERROR); intl_errors_set_custom_msg(TIMEZONE_ERROR_P(to_orig), "Could not clone IntlTimeZone", 0); err_msg = intl_error_get_message(TIMEZONE_ERROR_P(to_orig)); zend_throw_exception(NULL, err_msg->val, 0); zend_string_free(err_msg); } else { to_new->utimezone = newTimeZone; } } else { zend_throw_exception(NULL, "Cannot clone unconstructed IntlTimeZone", 0); } return ret_val; }
/* {{{ clone handler for Calendar */ static zend_object *Calendar_clone_obj(zval *object) { Calendar_object *co_orig, *co_new; zend_object *ret_val; intl_error_reset(NULL); co_orig = Z_INTL_CALENDAR_P(object); intl_error_reset(INTL_DATA_ERROR_P(co_orig)); ret_val = Calendar_ce_ptr->create_object(Z_OBJCE_P(object)); co_new = php_intl_calendar_fetch_object(ret_val); zend_objects_clone_members(&co_new->zo, &co_orig->zo); if (co_orig->ucal != NULL) { Calendar *newCalendar; newCalendar = co_orig->ucal->clone(); if (!newCalendar) { zend_string *err_msg; intl_errors_set_code(CALENDAR_ERROR_P(co_orig), U_MEMORY_ALLOCATION_ERROR); intl_errors_set_custom_msg(CALENDAR_ERROR_P(co_orig), "Could not clone IntlCalendar", 0); err_msg = intl_error_get_message(CALENDAR_ERROR_P(co_orig)); zend_throw_exception(NULL, err_msg->val, 0); zend_string_free(err_msg); } else { co_new->ucal = newCalendar; } } else { zend_throw_exception(NULL, "Cannot clone unconstructed IntlCalendar", 0); } return ret_val; }
/* {{{ intl_convert_utf16_to_utf8 * Convert given string from UTF-16 to UTF-8. * * @param source String to convert. * @param source_len Length of the source string. * @param status Conversion status. * * @return zend_string */ zend_string* intl_convert_utf16_to_utf8( const UChar* src, int32_t src_len, UErrorCode* status ) { zend_string* dst; int32_t dst_len; /* Determine required destination buffer size (pre-flighting). */ *status = U_ZERO_ERROR; u_strToUTF8( NULL, 0, &dst_len, src, src_len, status ); /* Bail out if an unexpected error occurred. * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough). * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty). */ if( *status != U_BUFFER_OVERFLOW_ERROR && *status != U_STRING_NOT_TERMINATED_WARNING ) return NULL; /* Allocate memory for the destination buffer (it will be zero-terminated). */ dst = zend_string_alloc(dst_len, 0); /* Convert source string from UTF-8 to UTF-16. */ *status = U_ZERO_ERROR; u_strToUTF8( ZSTR_VAL(dst), dst_len, NULL, src, src_len, status ); if( U_FAILURE( *status ) ) { zend_string_free(dst); return NULL; } /* U_STRING_NOT_TERMINATED_WARNING is OK for us => reset 'status'. */ *status = U_ZERO_ERROR; ZSTR_VAL(dst)[dst_len] = 0; return dst; }
/* {{{ php_mail */ PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd) { #if (defined PHP_WIN32 || defined NETWARE) int tsm_err; char *tsm_errmsg = NULL; #endif FILE *sendmail; int ret; char *sendmail_path = INI_STR("sendmail_path"); char *sendmail_cmd = NULL; char *mail_log = INI_STR("mail.log"); char *hdr = headers; #if PHP_SIGCHILD void (*sig_handler)() = NULL; #endif #define MAIL_RET(val) \ if (hdr != headers) { \ efree(hdr); \ } \ return val; \ if (mail_log && *mail_log) { char *tmp; time_t curtime; size_t l; zend_string *date_str; time(&curtime); date_str = php_format_date("d-M-Y H:i:s e", 13, curtime, 1); l = spprintf(&tmp, 0, "[%s] mail() on [%s:%d]: To: %s -- Headers: %s\n", date_str->val, zend_get_executed_filename(), zend_get_executed_lineno(), to, hdr ? hdr : ""); zend_string_free(date_str); if (hdr) { php_mail_log_crlf_to_spaces(tmp); } if (!strcmp(mail_log, "syslog")) { /* Drop the final space when logging to syslog. */ tmp[l - 1] = 0; php_mail_log_to_syslog(tmp); } else { /* Convert the final space to a newline when logging to file. */ tmp[l - 1] = '\n'; php_mail_log_to_file(mail_log, tmp, l); } efree(tmp); } if (PG(mail_x_header)) { const char *tmp = zend_get_executed_filename(); zend_string *f; f = php_basename(tmp, strlen(tmp), NULL, 0); if (headers != NULL) { spprintf(&hdr, 0, "X-PHP-Originating-Script: " ZEND_LONG_FMT ":%s\n%s", php_getuid(), f->val, headers); } else { spprintf(&hdr, 0, "X-PHP-Originating-Script: " ZEND_LONG_FMT ":%s", php_getuid(), f->val); } zend_string_release(f); } if (!sendmail_path) { #if (defined PHP_WIN32 || defined NETWARE) /* handle old style win smtp sending */ if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message, NULL, NULL, NULL) == FAILURE) { if (tsm_errmsg) { php_error_docref(NULL, E_WARNING, "%s", tsm_errmsg); efree(tsm_errmsg); } else { php_error_docref(NULL, E_WARNING, "%s", GetSMErrorText(tsm_err)); } MAIL_RET(0); } MAIL_RET(1); #else MAIL_RET(0); #endif } if (extra_cmd != NULL) { spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, extra_cmd); } else { sendmail_cmd = sendmail_path; } #if PHP_SIGCHILD /* Set signal handler of SIGCHLD to default to prevent other signal handlers * from being called and reaping the return code when our child exits. * The original handler needs to be restored after pclose() */ sig_handler = (void *)signal(SIGCHLD, SIG_DFL); if (sig_handler == SIG_ERR) { sig_handler = NULL; } #endif #ifdef PHP_WIN32 sendmail = popen_ex(sendmail_cmd, "wb", NULL, NULL); #else /* Since popen() doesn't indicate if the internal fork() doesn't work * (e.g. the shell can't be executed) we explicitly set it to 0 to be * sure we don't catch any older errno value. */ errno = 0; sendmail = popen(sendmail_cmd, "w"); #endif if (extra_cmd != NULL) { efree (sendmail_cmd); } if (sendmail) { #ifndef PHP_WIN32 if (EACCES == errno) { php_error_docref(NULL, E_WARNING, "Permission denied: unable to execute shell to run mail delivery binary '%s'", sendmail_path); pclose(sendmail); #if PHP_SIGCHILD /* Restore handler in case of error on Windows Not sure if this applicable on Win but just in case. */ if (sig_handler) { signal(SIGCHLD, sig_handler); } #endif MAIL_RET(0); } #endif fprintf(sendmail, "To: %s\n", to); fprintf(sendmail, "Subject: %s\n", subject); if (hdr != NULL) { fprintf(sendmail, "%s\n", hdr); } fprintf(sendmail, "\n%s\n", message); ret = pclose(sendmail); #if PHP_SIGCHILD if (sig_handler) { signal(SIGCHLD, sig_handler); } #endif #ifdef PHP_WIN32 if (ret == -1) #else #if defined(EX_TEMPFAIL) if ((ret != EX_OK)&&(ret != EX_TEMPFAIL)) #elif defined(EX_OK) if (ret != EX_OK) #else if (ret != 0) #endif #endif { MAIL_RET(0); } else { MAIL_RET(1); } } else { php_error_docref(NULL, E_WARNING, "Could not execute mail delivery program '%s'", sendmail_path); #if PHP_SIGCHILD if (sig_handler) { signal(SIGCHLD, sig_handler); } #endif MAIL_RET(0); } MAIL_RET(1); /* never reached */ }
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); } }
/********************************************************************* // Name: PostHeader // Input: 1) return path // 2) Subject // 3) destination address // 4) headers // Output: Error code or Success // Description: // Author/Date: jcar 20/9/96 // History: //********************************************************************/ static int PostHeader(char *RPath, char *Subject, char *mailTo, char *xheaders) { /* Print message header according to RFC 822 */ /* Return-path, Received, Date, From, Subject, Sender, To, cc */ int res; char *header_buffer; char *headers_lc = NULL; size_t i; if (xheaders) { size_t headers_lc_len; headers_lc = estrdup(xheaders); headers_lc_len = strlen(headers_lc); for (i = 0; i < headers_lc_len; i++) { headers_lc[i] = tolower(headers_lc[i]); } } header_buffer = ecalloc(1, MAIL_BUFFER_SIZE); if (!xheaders || !strstr(headers_lc, "date:")) { time_t tNow = time(NULL); zend_string *dt = php_format_date("r", 1, tNow, 1); snprintf(header_buffer, MAIL_BUFFER_SIZE, "Date: %s\r\n", ZSTR_VAL(dt)); zend_string_free(dt); } if (!headers_lc || !strstr(headers_lc, "from:")) { if (!addToHeader(&header_buffer, "From: %s\r\n", RPath)) { goto PostHeader_outofmem; } } if (!addToHeader(&header_buffer, "Subject: %s\r\n", Subject)) { goto PostHeader_outofmem; } /* Only add the To: field from the $to parameter if isn't in the custom headers */ if ((headers_lc && (!strstr(headers_lc, "\r\nto:") && (strncmp(headers_lc, "to:", 3) != 0))) || !headers_lc) { if (!addToHeader(&header_buffer, "To: %s\r\n", mailTo)) { goto PostHeader_outofmem; } } if (xheaders) { if (!addToHeader(&header_buffer, "%s\r\n", xheaders)) { goto PostHeader_outofmem; } } if (headers_lc) { efree(headers_lc); } if ((res = Post(header_buffer)) != SUCCESS) { efree(header_buffer); return (res); } efree(header_buffer); if ((res = Post("\r\n")) != SUCCESS) { return (res); } return (SUCCESS); PostHeader_outofmem: if (headers_lc) { efree(headers_lc); } return OUT_OF_MEMORY; }
/********************************************************************* // Name: SendText // Input: 1) RPath: return path of the message // Is used to fill the "Return-Path" and the // "X-Sender" fields of the message. // 2) Subject: Subject field of the message. If NULL is given // the subject is set to "No Subject" // 3) mailTo: Destination address // 4) data: Null terminated string containing the data to be send. // 5,6) headers of the message. Note that the second // parameter, headers_lc, is actually a lowercased version of // headers. The should match exactly (in terms of length), // only differ in case // Output: Error code or SUCCESS // Description: // Author/Date: jcar 20/9/96 // History: //*******************************************************************/ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char *mailBcc, char *data, char *headers, char *headers_lc, char **error_message) { int res; char *p; char *tempMailTo, *token, *pos1, *pos2; char *server_response = NULL; char *stripped_header = NULL; zend_string *data_cln; /* check for NULL parameters */ if (data == NULL) return (BAD_MSG_CONTENTS); if (mailTo == NULL) return (BAD_MSG_DESTINATION); if (RPath == NULL) return (BAD_MSG_RPATH); /* simple checks for the mailto address */ /* have ampersand ? */ /* mfischer, 20020514: I commented this out because it really seems bogus. Only a username for example may still be a valid address at the destination system. if (strchr(mailTo, '@') == NULL) return (BAD_MSG_DESTINATION); */ snprintf(PW32G(mail_buffer), sizeof(PW32G(mail_buffer)), "HELO %s\r\n", PW32G(mail_local_host)); /* in the beginning of the dialog */ /* attempt reconnect if the first Post fail */ if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { int err = MailConnect(); if (0 != err) { return (FAILED_TO_SEND); } if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { return (res); } } if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); return (res); } SMTP_SKIP_SPACE(RPath); FormatEmailAddress(PW32G(mail_buffer), RPath, "MAIL FROM:<%s>\r\n"); if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { return (res); } if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); return W32_SM_SENDMAIL_FROM_MALFORMED; } tempMailTo = estrdup(mailTo); /* Send mail to all rcpt's */ token = strtok(tempMailTo, ","); while (token != NULL) { SMTP_SKIP_SPACE(token); FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); efree(tempMailTo); return (res); } token = strtok(NULL, ","); } efree(tempMailTo); if (mailCc && *mailCc) { tempMailTo = estrdup(mailCc); /* Send mail to all rcpt's */ token = strtok(tempMailTo, ","); while (token != NULL) { SMTP_SKIP_SPACE(token); FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); efree(tempMailTo); return (res); } token = strtok(NULL, ","); } efree(tempMailTo); } /* Send mail to all Cc rcpt's */ else if (headers && (pos1 = strstr(headers_lc, "cc:")) && ((pos1 == headers_lc) || (*(pos1-1) == '\n'))) { /* Real offset is memaddress from the original headers + difference of * string found in the lowercase headrs + 3 characters to jump over * the cc: */ pos1 = headers + (pos1 - headers_lc) + 3; if (NULL == (pos2 = strstr(pos1, "\r\n"))) { tempMailTo = estrndup(pos1, strlen(pos1)); } else { tempMailTo = estrndup(pos1, pos2 - pos1); } token = strtok(tempMailTo, ","); while (token != NULL) { SMTP_SKIP_SPACE(token); FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); efree(tempMailTo); return (res); } token = strtok(NULL, ","); } efree(tempMailTo); } /* Send mail to all Bcc rcpt's This is basically a rip of the Cc code above. Just don't forget to remove the Bcc: from the header afterwards. */ if (mailBcc && *mailBcc) { tempMailTo = estrdup(mailBcc); /* Send mail to all rcpt's */ token = strtok(tempMailTo, ","); while (token != NULL) { SMTP_SKIP_SPACE(token); FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); efree(tempMailTo); return (res); } token = strtok(NULL, ","); } efree(tempMailTo); } else if (headers) { if ((pos1 = strstr(headers_lc, "bcc:")) && (pos1 == headers_lc || *(pos1-1) == '\n')) { /* Real offset is memaddress from the original headers + difference of * string found in the lowercase headrs + 4 characters to jump over * the bcc: */ pos1 = headers + (pos1 - headers_lc) + 4; if (NULL == (pos2 = strstr(pos1, "\r\n"))) { tempMailTo = estrndup(pos1, strlen(pos1)); /* Later, when we remove the Bcc: out of the header we know it was the last thing. */ pos2 = pos1; } else { tempMailTo = estrndup(pos1, pos2 - pos1); } token = strtok(tempMailTo, ","); while (token != NULL) { SMTP_SKIP_SPACE(token); FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); efree(tempMailTo); return (res); } token = strtok(NULL, ","); } efree(tempMailTo); /* Now that we've identified that we've a Bcc list, remove it from the current header. */ stripped_header = ecalloc(1, strlen(headers)); /* headers = point to string start of header pos1 = pointer IN headers where the Bcc starts '4' = Length of the characters 'bcc:' Because we've added +4 above for parsing the Emails we've to subtract them here. */ memcpy(stripped_header, headers, pos1 - headers - 4); if (pos1 != pos2) { /* if pos1 != pos2 , pos2 points to the rest of the headers. Since pos1 != pos2 if "\r\n" was found, we know those characters are there and so we jump over them (else we would generate a new header which would look like "\r\n\r\n". */ memcpy(stripped_header + (pos1 - headers - 4), pos2 + 2, strlen(pos2) - 2); } } } /* Simplify the code that we create a copy of stripped_header no matter if we actually strip something or not. So we've a single efree() later. */ if (headers && !stripped_header) { stripped_header = estrndup(headers, strlen(headers)); } if ((res = Post("DATA\r\n")) != SUCCESS) { if (stripped_header) { efree(stripped_header); } return (res); } if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); if (stripped_header) { efree(stripped_header); } return (res); } /* send message header */ if (Subject == NULL) { res = PostHeader(RPath, "No Subject", mailTo, stripped_header); } else { res = PostHeader(RPath, Subject, mailTo, stripped_header); } if (stripped_header) { efree(stripped_header); } if (res != SUCCESS) { return (res); } /* Escape \n. sequences * We use php_str_to_str() and not php_str_replace_in_subject(), since the latter * uses ZVAL as it's parameters */ data_cln = php_str_to_str(data, strlen(data), PHP_WIN32_MAIL_DOT_PATTERN, sizeof(PHP_WIN32_MAIL_DOT_PATTERN) - 1, PHP_WIN32_MAIL_DOT_REPLACE, sizeof(PHP_WIN32_MAIL_DOT_REPLACE) - 1); if (!data_cln) { data_cln = ZSTR_EMPTY_ALLOC(); } /* send message contents in 1024 chunks */ { char c, *e2, *e = ZSTR_VAL(data_cln) + ZSTR_LEN(data_cln); p = ZSTR_VAL(data_cln); while (e - p > 1024) { e2 = p + 1024; c = *e2; *e2 = '\0'; if ((res = Post(p)) != SUCCESS) { zend_string_free(data_cln); return(res); } *e2 = c; p = e2; } if ((res = Post(p)) != SUCCESS) { zend_string_free(data_cln); return(res); } } zend_string_free(data_cln); /*send termination dot */ if ((res = Post("\r\n.\r\n")) != SUCCESS) return (res); if ((res = Ack(&server_response)) != SUCCESS) { SMTP_ERROR_RESPONSE(server_response); return (res); } return (SUCCESS); }
/********************************************************************* // Name: TSendMail // Input: 1) host: Name of the mail host where the SMTP server resides // max accepted length of name = 256 // 2) appname: Name of the application to use in the X-mailer // field of the message. if NULL is given the application // name is used as given by the GetCommandLine() function // max accespted length of name = 100 // Output: 1) error: Returns the error code if something went wrong or // SUCCESS otherwise. // // See SendText() for additional args! //********************************************************************/ PHPAPI int TSendMail(char *host, int *error, char **error_message, char *headers, char *Subject, char *mailTo, char *data, char *mailCc, char *mailBcc, char *mailRPath) { int ret; char *RPath = NULL; zend_string *headers_lc = NULL, *headers_trim = NULL; /* headers_lc is only created if we've a header at all */ char *pos1 = NULL, *pos2 = NULL; if (host == NULL) { *error = BAD_MAIL_HOST; return FAILURE; } else if (strlen(host) >= HOST_NAME_LEN) { *error = BAD_MAIL_HOST; return FAILURE; } else { strcpy(PW32G(mail_host), host); } if (headers) { char *pos = NULL; /* Use PCRE to trim the header into the right format */ if (NULL == (headers_trim = php_win32_mail_trim_header(headers))) { *error = W32_SM_PCRE_ERROR; return FAILURE; } /* Create a lowercased header for all the searches so we're finally case * insensitive when searching for a pattern. */ headers_lc = zend_string_tolower(headers_trim); } /* Fall back to sendmail_from php.ini setting */ if (mailRPath && *mailRPath) { RPath = estrdup(mailRPath); } else if (INI_STR("sendmail_from")) { RPath = estrdup(INI_STR("sendmail_from")); } else if (headers_lc) { int found = 0; char *lookup = ZSTR_VAL(headers_lc); while (lookup) { pos1 = strstr(lookup, "from:"); if (!pos1) { break; } else if (pos1 != ZSTR_VAL(headers_lc) && *(pos1-1) != '\n') { if (strlen(pos1) >= sizeof("from:")) { lookup = pos1 + sizeof("from:"); continue; } else { break; } } found = 1; /* Real offset is memaddress from the original headers + difference of * string found in the lowercase headrs + 5 characters to jump over * the from: */ pos1 = headers + (pos1 - lookup) + 5; if (NULL == (pos2 = strstr(pos1, "\r\n"))) { RPath = estrndup(pos1, strlen(pos1)); } else { RPath = estrndup(pos1, pos2 - pos1); } break; } if (!found) { if (headers_lc) { zend_string_free(headers_lc); } *error = W32_SM_SENDMAIL_FROM_NOT_SET; return FAILURE; } } /* attempt to connect with mail host */ *error = MailConnect(); if (*error != 0) { if (RPath) { efree(RPath); } if (headers) { zend_string_free(headers_trim); zend_string_free(headers_lc); } /* 128 is safe here, the specifier in snprintf isn't longer than that */ *error_message = ecalloc(1, HOST_NAME_LEN + 128); snprintf(*error_message, HOST_NAME_LEN + 128, "Failed to connect to mailserver at \"%s\" port %d, verify your \"SMTP\" " "and \"smtp_port\" setting in php.ini or use ini_set()", PW32G(mail_host), !INI_INT("smtp_port") ? 25 : INI_INT("smtp_port")); return FAILURE; } else { ret = SendText(RPath, Subject, mailTo, mailCc, mailBcc, data, headers ? ZSTR_VAL(headers_trim) : NULL, headers ? ZSTR_VAL(headers_lc) : NULL, error_message); TSMClose(); if (RPath) { efree(RPath); } if (headers) { zend_string_free(headers_trim); zend_string_free(headers_lc); } if (ret != SUCCESS) { *error = ret; return FAILURE; } return SUCCESS; } }
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); } }
static int zephir_is_callable_check_class(const char *name, int name_len, zend_fcall_info_cache *fcc, int *strict_class, char **error) /* {{{ */ { int ret = 0; zend_class_entry *pce; char *lcname = zend_str_tolower_dup(name, name_len); *strict_class = 0; if (name_len == sizeof("self") - 1 && !memcmp(lcname, "self", sizeof("self") - 1)) { if (!EG(scope)) { if (error) *error = estrdup("cannot access self:: when no class scope is active"); } else { fcc->called_scope = EG(current_execute_data)->called_scope; if (!fcc->object) { fcc->object = Z_OBJ(EG(current_execute_data)->This); } ret = 1; } } else if (name_len == sizeof("parent") - 1 && !memcmp(lcname, "parent", sizeof("parent") - 1)) { if (!EG(scope)) { if (error) *error = estrdup("cannot access parent:: when no class scope is active"); } else if (!EG(scope)->parent) { if (error) *error = estrdup("cannot access parent:: when current class scope has no parent"); } else { fcc->called_scope = EG(current_execute_data)->called_scope; if (!fcc->object) { fcc->object = Z_OBJ(EG(current_execute_data)->This); } *strict_class = 1; ret = 1; } } else if (name_len == sizeof("static") - 1 && !memcmp(lcname, "static", sizeof("static") - 1)) { if (!EG(current_execute_data)->called_scope) { if (error) *error = estrdup("cannot access static:: when no class scope is active"); } else { fcc->called_scope = EG(current_execute_data)->called_scope; if (!fcc->object) { fcc->object = Z_OBJ(EG(current_execute_data)->This); } *strict_class = 1; ret = 1; } } else { zend_string *class_name; class_name = zend_string_init(name, name_len, 0); if ((pce = zend_lookup_class_ex(class_name, NULL, 1)) != NULL) { zend_class_entry *scope = EG(current_execute_data) ? EG(current_execute_data)->func->common.scope : NULL; fcc->calling_scope = pce; if (scope && !fcc->object && EG(current_execute_data) && Z_OBJ(EG(current_execute_data)->This) && instanceof_function(Z_OBJCE(EG(current_execute_data)->This), scope TSRMLS_CC) && instanceof_function(scope, fcc->calling_scope TSRMLS_CC)) { fcc->object = Z_OBJ(EG(current_execute_data)->This); fcc->called_scope = fcc->object->ce; } else { fcc->called_scope = fcc->object ? fcc->object->ce : fcc->calling_scope; } *strict_class = 1; ret = 1; } else { if (error) zephir_spprintf(error, 0, "class '%.*s' not found", name_len, name); } zend_string_free(class_name); } efree(lcname); return ret; }
/* {{{ php_url_encode_hash */ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, const char *num_prefix, size_t num_prefix_len, const char *key_prefix, size_t key_prefix_len, const char *key_suffix, size_t key_suffix_len, zval *type, char *arg_sep, int enc_type) { zend_string *key = NULL; char *newprefix, *p; const char *prop_name; size_t arg_sep_len, newprefix_len, prop_len; zend_ulong idx; zval *zdata = NULL; if (!ht) { return FAILURE; } if (GC_IS_RECURSIVE(ht)) { /* Prevent recursion */ return SUCCESS; } if (!arg_sep) { arg_sep = INI_STR("arg_separator.output"); if (!arg_sep || !strlen(arg_sep)) { arg_sep = URL_DEFAULT_ARG_SEP; } } arg_sep_len = strlen(arg_sep); ZEND_HASH_FOREACH_KEY_VAL(ht, idx, key, zdata) { zend_bool is_dynamic = 1; if (Z_TYPE_P(zdata) == IS_INDIRECT) { zdata = Z_INDIRECT_P(zdata); if (Z_ISUNDEF_P(zdata)) { continue; } is_dynamic = 0; } /* handling for private & protected object properties */ if (key) { prop_name = ZSTR_VAL(key); prop_len = ZSTR_LEN(key); if (type != NULL && zend_check_property_access(Z_OBJ_P(type), key, is_dynamic) != SUCCESS) { /* property not visible in this scope */ continue; } if (ZSTR_VAL(key)[0] == '\0' && type != NULL) { const char *tmp; zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len); } else { prop_name = ZSTR_VAL(key); prop_len = ZSTR_LEN(key); } } else { prop_name = NULL; prop_len = 0; } ZVAL_DEREF(zdata); if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) { if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } newprefix_len = key_suffix_len + ZSTR_LEN(ekey) + key_prefix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, ZSTR_VAL(ekey), ZSTR_LEN(ekey)); p += ZSTR_LEN(ekey); zend_string_free(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } else { char *ekey; size_t ekey_len; /* Is an integer key */ ekey_len = spprintf(&ekey, 0, ZEND_LONG_FMT, idx); newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, num_prefix, num_prefix_len); p += num_prefix_len; memcpy(p, ekey, ekey_len); p += ekey_len; efree(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { GC_PROTECT_RECURSION(ht); } php_url_encode_hash_ex(HASH_OF(zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_P(zdata) == IS_OBJECT ? zdata : NULL), arg_sep, enc_type); if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { GC_UNPROTECT_RECURSION(ht); } efree(newprefix); } else if (Z_TYPE_P(zdata) == IS_NULL || Z_TYPE_P(zdata) == IS_RESOURCE) { /* Skip these types */ continue; } else { if (formstr->s) { smart_str_appendl(formstr, arg_sep, arg_sep_len); } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } smart_str_append(formstr, ekey); zend_string_free(ekey); } else { /* Numeric key */ if (num_prefix) { smart_str_appendl(formstr, num_prefix, num_prefix_len); } smart_str_append_long(formstr, idx); } smart_str_appendl(formstr, key_suffix, key_suffix_len); smart_str_appendl(formstr, "=", 1); switch (Z_TYPE_P(zdata)) { case IS_STRING: { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } else { ekey = php_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } smart_str_append(formstr, ekey); zend_string_free(ekey); } break; case IS_LONG: smart_str_append_long(formstr, Z_LVAL_P(zdata)); break; case IS_FALSE: smart_str_appendl(formstr, "0", sizeof("0")-1); break; case IS_TRUE: smart_str_appendl(formstr, "1", sizeof("1")-1); break; case IS_DOUBLE: { char *ekey; size_t ekey_len; ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_P(zdata)); smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } break; default: { zend_string *ekey; zend_string *tmp; zend_string *str= zval_get_tmp_string(zdata, &tmp); if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(ZSTR_VAL(str), ZSTR_LEN(str)); } else { ekey = php_url_encode(ZSTR_VAL(str), ZSTR_LEN(str)); } smart_str_append(formstr, ekey); zend_tmp_string_release(tmp); zend_string_free(ekey); } } } } ZEND_HASH_FOREACH_END();
PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER) { const unsigned char *cursor, *limit, *marker, *start; zval *rval_ref; limit = max; cursor = *p; if (YYCURSOR >= YYLIMIT) { return 0; } if (var_hash && (*p)[0] != 'R') { var_push(var_hash, rval); } start = cursor; #line 518 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; switch (yych) { case 'C': case 'O': goto yy13; case 'N': goto yy5; case 'R': goto yy2; case 'S': goto yy10; case 'a': goto yy11; case 'b': goto yy6; case 'd': goto yy8; case 'i': goto yy7; case 'o': goto yy12; case 'r': goto yy4; case 's': goto yy9; case '}': goto yy14; default: goto yy16; } yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: #line 873 "ext/standard/var_unserializer.re" { return 0; } #line 580 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; goto yy3; yy5: yych = *++YYCURSOR; if (yych == ';') goto yy87; goto yy3; yy6: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy83; goto yy3; yy7: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy77; goto yy3; yy8: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy53; goto yy3; yy9: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy46; goto yy3; yy10: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy39; goto yy3; yy11: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy32; goto yy3; yy12: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy25; goto yy3; yy13: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy17; goto yy3; yy14: ++YYCURSOR; #line 867 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } #line 629 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; yy17: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } if (yych == '+') goto yy19; yy18: YYCURSOR = YYMARKER; goto yy3; yy19: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } goto yy18; yy20: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } if (yych <= '/') goto yy18; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 722 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; zend_long elements; char *str; zend_string *class_name; zend_class_entry *ce; int incomplete_class = 0; int custom_object = 0; zval user_func; zval retval; zval args[1]; if (!var_hash) return 0; if (*start == 'C') { custom_object = 1; } len2 = len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len || len == 0) { *p = start + 2; return 0; } str = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } if (*(YYCURSOR+1) != ':') { *p = YYCURSOR+1; return 0; } len3 = strspn(str, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\"); if (len3 != len) { *p = YYCURSOR + len3 - len; return 0; } class_name = zend_string_init(str, len, 0); do { if(!unserialize_allowed_class(class_name, classes)) { incomplete_class = 1; ce = PHP_IC_ENTRY; break; } /* Try to find class directly */ BG(serialize_lock)++; ce = zend_lookup_class(class_name); if (ce) { BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); return 0; } break; } BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); return 0; } /* Check for unserialize callback */ if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) { incomplete_class = 1; ce = PHP_IC_ENTRY; break; } /* Call unserialize callback */ ZVAL_STRING(&user_func, PG(unserialize_callback_func)); ZVAL_STR_COPY(&args[0], class_name); BG(serialize_lock)++; if (call_user_function_ex(CG(function_table), NULL, &user_func, &retval, 1, args, 0, NULL) != SUCCESS) { BG(serialize_lock)--; if (EG(exception)) { zend_string_release(class_name); zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); return 0; } php_error_docref(NULL, E_WARNING, "defined (%s) but not found", Z_STRVAL(user_func)); incomplete_class = 1; ce = PHP_IC_ENTRY; zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); break; } BG(serialize_lock)--; zval_ptr_dtor(&retval); if (EG(exception)) { zend_string_release(class_name); zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); return 0; } /* The callback function may have defined the class */ if ((ce = zend_lookup_class(class_name)) == NULL) { php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func)); incomplete_class = 1; ce = PHP_IC_ENTRY; } zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); break; } while (1); *p = YYCURSOR; if (custom_object) { int ret; ret = object_custom(UNSERIALIZE_PASSTHRU, ce); if (ret && incomplete_class) { php_store_class_name(rval, ZSTR_VAL(class_name), len2); } zend_string_release(class_name); return ret; } elements = object_common1(UNSERIALIZE_PASSTHRU, ce); if (incomplete_class) { php_store_class_name(rval, ZSTR_VAL(class_name), len2); } zend_string_release(class_name); return object_common2(UNSERIALIZE_PASSTHRU, elements); } #line 805 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy26; if (yych <= '/') goto yy18; if (yych <= '9') goto yy27; goto yy18; } yy26: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy27: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy27; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 715 "ext/standard/var_unserializer.re" { if (!var_hash) return 0; return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } #line 837 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; goto yy18; yy33: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy34: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; #line 691 "ext/standard/var_unserializer.re" { zend_long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ *p = YYCURSOR; if (!var_hash) return 0; if (elements < 0) { return 0; } array_init_size(rval, elements); //??? we can't convert from packed to hash during unserialization, because //??? reference to some zvals might be keept in var_hash (to support references) if (elements) { zend_hash_real_init(Z_ARRVAL_P(rval), 0); } if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) { return 0; } return finish_nested_data(UNSERIALIZE_PASSTHRU); } #line 882 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; if (yych <= '/') goto yy18; if (yych <= '9') goto yy41; goto yy18; yy40: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy41: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy41; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 663 "ext/standard/var_unserializer.re" { size_t len, maxlen; zend_string *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } if ((str = unserialize_str(&YYCURSOR, len, maxlen)) == NULL) { return 0; } if (*(YYCURSOR) != '"') { zend_string_free(str); *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; ZVAL_STR(rval, str); return 1; } #line 931 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; if (yych <= '/') goto yy18; if (yych <= '9') goto yy48; goto yy18; yy47: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy48: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy48; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 636 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } str = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; ZVAL_STRINGL(rval, str, len); return 1; } #line 979 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { if (yych <= ',') { if (yych == '+') goto yy57; goto yy18; } else { if (yych <= '-') goto yy55; if (yych <= '.') goto yy60; goto yy18; } } else { if (yych <= 'I') { if (yych <= '9') goto yy58; if (yych <= 'H') goto yy18; goto yy56; } else { if (yych != 'N') goto yy18; } } yych = *++YYCURSOR; if (yych == 'A') goto yy76; goto yy18; yy55: yych = *++YYCURSOR; if (yych <= '/') { if (yych == '.') goto yy60; goto yy18; } else { if (yych <= '9') goto yy58; if (yych != 'I') goto yy18; } yy56: yych = *++YYCURSOR; if (yych == 'N') goto yy72; goto yy18; yy57: yych = *++YYCURSOR; if (yych == '.') goto yy60; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy58: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ':') { if (yych <= '.') { if (yych <= '-') goto yy18; goto yy70; } else { if (yych <= '/') goto yy18; if (yych <= '9') goto yy58; goto yy18; } } else { if (yych <= 'E') { if (yych <= ';') goto yy63; if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy60: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy61: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy61; if (yych <= ':') goto yy18; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy63: ++YYCURSOR; #line 627 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 use_double: #endif *p = YYCURSOR; ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); return 1; } #line 1076 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy66; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; goto yy18; } yy66: yych = *++YYCURSOR; if (yych <= ',') { if (yych == '+') goto yy69; goto yy18; } else { if (yych <= '-') goto yy69; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; } yy67: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; if (yych == ';') goto yy63; goto yy18; yy69: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; goto yy18; yy70: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy70; if (yych <= ':') goto yy18; goto yy63; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy72: yych = *++YYCURSOR; if (yych != 'F') goto yy18; yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; #line 611 "ext/standard/var_unserializer.re" { *p = YYCURSOR; if (!strncmp((char*)start + 2, "NAN", 3)) { ZVAL_DOUBLE(rval, php_get_nan()); } else if (!strncmp((char*)start + 2, "INF", 3)) { ZVAL_DOUBLE(rval, php_get_inf()); } else if (!strncmp((char*)start + 2, "-INF", 4)) { ZVAL_DOUBLE(rval, -php_get_inf()); } else { ZVAL_NULL(rval); } return 1; } #line 1151 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; goto yy18; yy77: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy78; if (yych <= '/') goto yy18; if (yych <= '9') goto yy79; goto yy18; } yy78: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy79: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; #line 585 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 int digits = YYCURSOR - start - 3; if (start[2] == '-' || start[2] == '+') { digits--; } /* Use double for large zend_long values that were serialized on a 64-bit system */ if (digits >= MAX_LENGTH_OF_LONG - 1) { if (digits == MAX_LENGTH_OF_LONG - 1) { int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1); if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) { goto use_double; } } else { goto use_double; } } #endif *p = YYCURSOR; ZVAL_LONG(rval, parse_iv(start + 2)); return 1; } #line 1204 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= '2') goto yy18; yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; #line 579 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_BOOL(rval, parse_iv(start + 2)); return 1; } #line 1218 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; #line 573 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_NULL(rval); return 1; } #line 1227 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy90; if (yych <= '/') goto yy18; if (yych <= '9') goto yy91; goto yy18; } yy90: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy91: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; #line 548 "ext/standard/var_unserializer.re" { zend_long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_iv(start + 2) - 1; if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } if (rval_ref == rval) { return 0; } if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { ZVAL_UNDEF(rval); return 1; } ZVAL_COPY(rval, rval_ref); return 1; } #line 1275 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy96; if (yych <= '/') goto yy18; if (yych <= '9') goto yy97; goto yy18; } yy96: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy97: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; #line 522 "ext/standard/var_unserializer.re" { zend_long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_iv(start + 2) - 1; if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } zval_ptr_dtor(rval); if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { ZVAL_UNDEF(rval); return 1; } if (Z_ISREF_P(rval_ref)) { ZVAL_COPY(rval, rval_ref); } else { ZVAL_NEW_REF(rval_ref, rval_ref); ZVAL_COPY(rval, rval_ref); } return 1; } #line 1324 "ext/standard/var_unserializer.c" } #line 875 "ext/standard/var_unserializer.re" return 0; }
int fpm_status_handle_request(void) /* {{{ */ { struct fpm_scoreboard_s scoreboard, *scoreboard_p; struct fpm_scoreboard_proc_s proc; char *buffer, *time_format, time_buffer[64]; time_t now_epoch; int full, encode; char *short_syntax, *short_post; char *full_pre, *full_syntax, *full_post, *full_separator; zend_string *_GET_str; if (!SG(request_info).request_uri) { return 0; } /* PING */ if (fpm_status_ping_uri && fpm_status_ping_response && !strcmp(fpm_status_ping_uri, SG(request_info).request_uri)) { fpm_request_executing(); sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1); SG(sapi_headers).http_response_code = 200; /* handle HEAD */ if (SG(request_info).headers_only) { return 1; } PUTS(fpm_status_ping_response); return 1; } /* STATUS */ if (fpm_status_uri && !strcmp(fpm_status_uri, SG(request_info).request_uri)) { fpm_request_executing(); scoreboard_p = fpm_scoreboard_get(); if (!scoreboard_p) { zlog(ZLOG_ERROR, "status: unable to find or access status shared memory"); SG(sapi_headers).http_response_code = 500; sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1); PUTS("Internal error. Please review log file for errors."); return 1; } if (!fpm_spinlock(&scoreboard_p->lock, 1)) { zlog(ZLOG_NOTICE, "[pool %s] status: scoreboard already in used.", scoreboard_p->pool); SG(sapi_headers).http_response_code = 503; sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1); PUTS("Server busy. Please try again later."); return 1; } /* copy the scoreboard not to bother other processes */ scoreboard = *scoreboard_p; fpm_unlock(scoreboard_p->lock); if (scoreboard.idle < 0 || scoreboard.active < 0) { zlog(ZLOG_ERROR, "[pool %s] invalid status values", scoreboard.pool); SG(sapi_headers).http_response_code = 500; sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1); PUTS("Internal error. Please review log file for errors."); return 1; } /* send common headers */ sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1); sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1); SG(sapi_headers).http_response_code = 200; /* handle HEAD */ if (SG(request_info).headers_only) { return 1; } /* full status ? */ _GET_str = zend_string_init("_GET", sizeof("_GET")-1, 0); full = (fpm_php_get_string_from_table(_GET_str, "full") != NULL); short_syntax = short_post = NULL; full_separator = full_pre = full_syntax = full_post = NULL; encode = 0; /* HTML */ if (fpm_php_get_string_from_table(_GET_str, "html")) { sapi_add_header_ex(ZEND_STRL("Content-Type: text/html"), 1, 1); time_format = "%d/%b/%Y:%H:%M:%S %z"; encode = 1; short_syntax = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" "<head><title>PHP-FPM Status Page</title></head>\n" "<body>\n" "<table>\n" "<tr><th>pool</th><td>%s</td></tr>\n" "<tr><th>process manager</th><td>%s</td></tr>\n" "<tr><th>start time</th><td>%s</td></tr>\n" "<tr><th>start since</th><td>%lu</td></tr>\n" "<tr><th>accepted conn</th><td>%lu</td></tr>\n" #ifdef HAVE_FPM_LQ "<tr><th>listen queue</th><td>%u</td></tr>\n" "<tr><th>max listen queue</th><td>%u</td></tr>\n" "<tr><th>listen queue len</th><td>%d</td></tr>\n" #endif "<tr><th>idle processes</th><td>%d</td></tr>\n" "<tr><th>active processes</th><td>%d</td></tr>\n" "<tr><th>total processes</th><td>%d</td></tr>\n" "<tr><th>max active processes</th><td>%d</td></tr>\n" "<tr><th>max children reached</th><td>%u</td></tr>\n" "<tr><th>slow requests</th><td>%lu</td></tr>\n" "</table>\n"; if (!full) { short_post = "</body></html>"; } else { full_pre = "<table border=\"1\">\n" "<tr>" "<th>pid</th>" "<th>state</th>" "<th>start time</th>" "<th>start since</th>" "<th>requests</th>" "<th>request duration</th>" "<th>request method</th>" "<th>request uri</th>" "<th>content length</th>" "<th>user</th>" "<th>script</th>" #ifdef HAVE_FPM_LQ "<th>last request cpu</th>" #endif "<th>last request memory</th>" "</tr>\n"; full_syntax = "<tr>" "<td>%d</td>" "<td>%s</td>" "<td>%s</td>" "<td>%lu</td>" "<td>%lu</td>" "<td>%lu</td>" "<td>%s</td>" "<td>%s%s%s</td>" "<td>%zu</td>" "<td>%s</td>" "<td>%s</td>" #ifdef HAVE_FPM_LQ "<td>%.2f</td>" #endif "<td>%zu</td>" "</tr>\n"; full_post = "</table></body></html>"; } /* XML */ } else if (fpm_php_get_string_from_table(_GET_str, "xml")) { sapi_add_header_ex(ZEND_STRL("Content-Type: text/xml"), 1, 1); time_format = "%s"; encode = 1; short_syntax = "<?xml version=\"1.0\" ?>\n" "<status>\n" "<pool>%s</pool>\n" "<process-manager>%s</process-manager>\n" "<start-time>%s</start-time>\n" "<start-since>%lu</start-since>\n" "<accepted-conn>%lu</accepted-conn>\n" #ifdef HAVE_FPM_LQ "<listen-queue>%u</listen-queue>\n" "<max-listen-queue>%u</max-listen-queue>\n" "<listen-queue-len>%d</listen-queue-len>\n" #endif "<idle-processes>%d</idle-processes>\n" "<active-processes>%d</active-processes>\n" "<total-processes>%d</total-processes>\n" "<max-active-processes>%d</max-active-processes>\n" "<max-children-reached>%u</max-children-reached>\n" "<slow-requests>%lu</slow-requests>\n"; if (!full) { short_post = "</status>"; } else { full_pre = "<processes>\n"; full_syntax = "<process>" "<pid>%d</pid>" "<state>%s</state>" "<start-time>%s</start-time>" "<start-since>%lu</start-since>" "<requests>%lu</requests>" "<request-duration>%lu</request-duration>" "<request-method>%s</request-method>" "<request-uri>%s%s%s</request-uri>" "<content-length>%zu</content-length>" "<user>%s</user>" "<script>%s</script>" #ifdef HAVE_FPM_LQ "<last-request-cpu>%.2f</last-request-cpu>" #endif "<last-request-memory>%zu</last-request-memory>" "</process>\n" ; full_post = "</processes>\n</status>"; } /* JSON */ } else if (fpm_php_get_string_from_table(_GET_str, "json")) { sapi_add_header_ex(ZEND_STRL("Content-Type: application/json"), 1, 1); time_format = "%s"; short_syntax = "{" "\"pool\":\"%s\"," "\"process manager\":\"%s\"," "\"start time\":%s," "\"start since\":%lu," "\"accepted conn\":%lu," #ifdef HAVE_FPM_LQ "\"listen queue\":%u," "\"max listen queue\":%u," "\"listen queue len\":%d," #endif "\"idle processes\":%d," "\"active processes\":%d," "\"total processes\":%d," "\"max active processes\":%d," "\"max children reached\":%u," "\"slow requests\":%lu"; if (!full) { short_post = "}"; } else { full_separator = ","; full_pre = ", \"processes\":["; full_syntax = "{" "\"pid\":%d," "\"state\":\"%s\"," "\"start time\":%s," "\"start since\":%lu," "\"requests\":%lu," "\"request duration\":%lu," "\"request method\":\"%s\"," "\"request uri\":\"%s%s%s\"," "\"content length\":%zu," "\"user\":\"%s\"," "\"script\":\"%s\"," #ifdef HAVE_FPM_LQ "\"last request cpu\":%.2f," #endif "\"last request memory\":%zu" "}"; full_post = "]}"; } /* TEXT */ } else { sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1); time_format = "%d/%b/%Y:%H:%M:%S %z"; short_syntax = "pool: %s\n" "process manager: %s\n" "start time: %s\n" "start since: %lu\n" "accepted conn: %lu\n" #ifdef HAVE_FPM_LQ "listen queue: %u\n" "max listen queue: %u\n" "listen queue len: %d\n" #endif "idle processes: %d\n" "active processes: %d\n" "total processes: %d\n" "max active processes: %d\n" "max children reached: %u\n" "slow requests: %lu\n"; if (full) { full_syntax = "\n" "************************\n" "pid: %d\n" "state: %s\n" "start time: %s\n" "start since: %lu\n" "requests: %lu\n" "request duration: %lu\n" "request method: %s\n" "request URI: %s%s%s\n" "content length: %zu\n" "user: %s\n" "script: %s\n" #ifdef HAVE_FPM_LQ "last request cpu: %.2f\n" #endif "last request memory: %zu\n"; } } strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&scoreboard.start_epoch)); now_epoch = time(NULL); spprintf(&buffer, 0, short_syntax, scoreboard.pool, PM2STR(scoreboard.pm), time_buffer, now_epoch - scoreboard.start_epoch, scoreboard.requests, #ifdef HAVE_FPM_LQ scoreboard.lq, scoreboard.lq_max, scoreboard.lq_len, #endif scoreboard.idle, scoreboard.active, scoreboard.idle + scoreboard.active, scoreboard.active_max, scoreboard.max_children_reached, scoreboard.slow_rq); PUTS(buffer); efree(buffer); zend_string_release(_GET_str); if (short_post) { PUTS(short_post); } /* no need to test the var 'full' */ if (full_syntax) { unsigned int i; int first; zend_string *tmp_query_string; char *query_string; struct timeval duration, now; #ifdef HAVE_FPM_LQ float cpu; #endif fpm_clock_get(&now); if (full_pre) { PUTS(full_pre); } first = 1; for (i=0; i<scoreboard_p->nprocs; i++) { if (!scoreboard_p->procs[i] || !scoreboard_p->procs[i]->used) { continue; } proc = *scoreboard_p->procs[i]; if (first) { first = 0; } else { if (full_separator) { PUTS(full_separator); } } query_string = NULL; tmp_query_string = NULL; if (proc.query_string[0] != '\0') { if (!encode) { query_string = proc.query_string; } else { tmp_query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, 1); query_string = ZSTR_VAL(tmp_query_string); } } #ifdef HAVE_FPM_LQ /* prevent NaN */ if (proc.cpu_duration.tv_sec == 0 && proc.cpu_duration.tv_usec == 0) { cpu = 0.; } else { cpu = (proc.last_request_cpu.tms_utime + proc.last_request_cpu.tms_stime + proc.last_request_cpu.tms_cutime + proc.last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() / (proc.cpu_duration.tv_sec + proc.cpu_duration.tv_usec / 1000000.) * 100.; } #endif if (proc.request_stage == FPM_REQUEST_ACCEPTING) { duration = proc.duration; } else { timersub(&now, &proc.accepted, &duration); } strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&proc.start_epoch)); spprintf(&buffer, 0, full_syntax, proc.pid, fpm_request_get_stage_name(proc.request_stage), time_buffer, now_epoch - proc.start_epoch, proc.requests, duration.tv_sec * 1000000UL + duration.tv_usec, proc.request_method[0] != '\0' ? proc.request_method : "-", proc.request_uri[0] != '\0' ? proc.request_uri : "-", query_string ? "?" : "", query_string ? query_string : "", proc.content_length, proc.auth_user[0] != '\0' ? proc.auth_user : "******", proc.script_filename[0] != '\0' ? proc.script_filename : "-", #ifdef HAVE_FPM_LQ proc.request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0., #endif proc.request_stage == FPM_REQUEST_ACCEPTING ? proc.memory : 0); PUTS(buffer); efree(buffer); if (tmp_query_string) { zend_string_free(tmp_query_string); } } if (full_post) { PUTS(full_post); } } return 1; } return 0; }