int shurrik_hash_apply_for_array(zval **val,int num_args,va_list args,zend_hash_key *hash_key) { TSRMLS_FETCH(); php_printf(" "); if (hash_key->nKeyLength) { //如果是字符串类型的key PHPWRITE(hash_key->arKey, hash_key->nKeyLength); } else { //如果是数字类型的key php_printf("%ld", hash_key->h); } php_printf("=>"); if(Z_TYPE_PP(val) == IS_ARRAY){ //php_printf("%d",(**tmp).type); //zend_hash_apply((**val).value.ht,shurrik_hash_apply_for_zval, 0); /*if(Z_TYPE_PP(tmp) == IS_STRING){ php_printf("%s",(**tmp).value.str.val); }*/ Bucket *p; zval **tmp; p = (**val).value.ht->pListHead; if(p == NULL){ return ZEND_HASH_APPLY_STOP; } php_printf("array(\n"); while (p != NULL) { php_printf(" "); tmp = p->pData; if(p->nKeyLength){ php_printf("%s=>",p->arKey); }else { php_printf("%ld=>",p->h); } if(Z_TYPE_PP(tmp) == IS_STRING){ php_printf("%s\n",(**tmp).value.str.val); } if(Z_TYPE_PP(tmp) == IS_ARRAY){ //php_printf("array()\n"); //shurrik_apply_array(tmp); //zend_hash_apply_with_arguments(((**tmp).value.ht)->pListHead->pData,shurrik_hash_apply_for_array, 0); //shurrik_hash_apply(tmp,p); //return shurrik_hash_apply_for_zval(tmp TSRMLS_CC); } p = p->pListNext; } php_printf(" );\n"); } if(Z_TYPE_PP(val) == IS_STRING){ php_printf("%s",(**val).value.str.val); } php_printf("\n"); //返回,继续遍历下一个~ return ZEND_HASH_APPLY_KEEP; }
PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval) { var_dtor_entries *var_hash = (*var_hashx)->last_dtor; #if VAR_ENTRIES_DBG fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); #endif if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = emalloc(sizeof(var_dtor_entries)); var_hash->used_slots = 0; var_hash->next = 0; if (!(*var_hashx)->first_dtor) { (*var_hashx)->first_dtor = var_hash; } else { ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash; } (*var_hashx)->last_dtor = var_hash; } ZVAL_COPY_VALUE(&var_hash->data[var_hash->used_slots], rval); var_hash->used_slots++; }
/* Used internally as comparison routine passed to zend_list_del_element */ static int curl_compare_resources( zval *z1, zval **z2 ) /* {{{ */ { return (Z_TYPE_P( z1 ) == Z_TYPE_PP( z2 ) && Z_TYPE_P( z1 ) == IS_RESOURCE && Z_LVAL_P( z1 ) == Z_LVAL_PP( z2 ) ); }
php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */ { php_stream *stream = NULL; php_url *resource = NULL; int use_ssl; int use_proxy = 0; char *scratch = NULL; char *tmp = NULL; char *ua_str = NULL; zval **ua_zval = NULL, **tmpzval = NULL; int scratch_len = 0; int body = 0; char location[HTTP_HEADER_BLOCK_SIZE]; zval *response_header = NULL; int reqok = 0; char *http_header_line = NULL; char tmp_line[128]; size_t chunk_size = 0, file_size = 0; int eol_detect = 0; char *transport_string, *errstr = NULL; int transport_len, have_header = 0, request_fulluri = 0, ignore_errors = 0; char *protocol_version = NULL; int protocol_version_len = 3; /* Default: "1.0" */ struct timeval timeout; char *user_headers = NULL; int header_init = ((flags & HTTP_WRAPPER_HEADER_INIT) != 0); int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0); int follow_location = 1; php_stream_filter *transfer_encoding = NULL; tmp_line[0] = '\0'; if (redirect_max < 1) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Redirection limit reached, aborting"); return NULL; } resource = php_url_parse(path); if (resource == NULL) { return NULL; } if (strncasecmp(resource->scheme, "http", sizeof("http")) && strncasecmp(resource->scheme, "https", sizeof("https"))) { if (!context || php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == FAILURE || Z_TYPE_PP(tmpzval) != IS_STRING || Z_STRLEN_PP(tmpzval) <= 0) { php_url_free(resource); return php_stream_open_wrapper_ex(path, mode, ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context); } /* Called from a non-http wrapper with http proxying requested (i.e. ftp) */ request_fulluri = 1; use_ssl = 0; use_proxy = 1; transport_len = Z_STRLEN_PP(tmpzval); transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval)); } else { /* Normal http request (possibly with proxy) */ if (strpbrk(mode, "awx+")) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper does not support writeable connections"); php_url_free(resource); return NULL; } use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's'; /* choose default ports */ if (use_ssl && resource->port == 0) resource->port = 443; else if (resource->port == 0) resource->port = 80; if (context && php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == SUCCESS && Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) { use_proxy = 1; transport_len = Z_STRLEN_PP(tmpzval); transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval)); } else { transport_len = spprintf(&transport_string, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", resource->host, resource->port); } } if (context && php_stream_context_get_option(context, wrapper->wops->label, "timeout", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_double_ex(tmpzval); timeout.tv_sec = (time_t) Z_DVAL_PP(tmpzval); timeout.tv_usec = (size_t) ((Z_DVAL_PP(tmpzval) - timeout.tv_sec) * 1000000); } else { timeout.tv_sec = FG(default_socket_timeout); timeout.tv_usec = 0; } stream = php_stream_xport_create(transport_string, transport_len, options, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, &timeout, context, &errstr, NULL); if (stream) { php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &timeout); } if (errstr) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s", errstr); efree(errstr); errstr = NULL; } efree(transport_string); if (stream && use_proxy && use_ssl) { smart_str header = {0}; smart_str_appendl(&header, "CONNECT ", sizeof("CONNECT ")-1); smart_str_appends(&header, resource->host); smart_str_appendc(&header, ':'); smart_str_append_unsigned(&header, resource->port); smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1); /* check if we have Proxy-Authorization header */ if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) { char *s, *p; if (Z_TYPE_PP(tmpzval) == IS_ARRAY) { HashPosition pos; zval **tmpheader = NULL; for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos); SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos); zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos)) { if (Z_TYPE_PP(tmpheader) == IS_STRING) { s = Z_STRVAL_PP(tmpheader); do { while (*s == ' ' || *s == '\t') s++; p = s; while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++; if (*p == ':') { p++; if (p - s == sizeof("Proxy-Authorization:") - 1 && zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1, "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) { while (*p != 0 && *p != '\r' && *p !='\n') p++; smart_str_appendl(&header, s, p - s); smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1); goto finish; } else { while (*p != 0 && *p != '\r' && *p !='\n') p++; } } s = p; while (*s == '\r' || *s == '\n') s++; } while (*s != 0); } } } else if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) { s = Z_STRVAL_PP(tmpzval); do { while (*s == ' ' || *s == '\t') s++; p = s; while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++; if (*p == ':') { p++; if (p - s == sizeof("Proxy-Authorization:") - 1 && zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1, "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) { while (*p != 0 && *p != '\r' && *p !='\n') p++; smart_str_appendl(&header, s, p - s); smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1); goto finish; } else { while (*p != 0 && *p != '\r' && *p !='\n') p++; } } s = p; while (*s == '\r' || *s == '\n') s++; } while (*s != 0); } } finish: smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1); if (php_stream_write(stream, header.c, header.len) != header.len) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy"); php_stream_close(stream); stream = NULL; } smart_str_free(&header); if (stream) { char header_line[HTTP_HEADER_BLOCK_SIZE]; /* get response header */ while (php_stream_gets(stream, header_line, HTTP_HEADER_BLOCK_SIZE-1) != NULL) { if (header_line[0] == '\n' || header_line[0] == '\r' || header_line[0] == '\0') { break; } } } /* enable SSL transport layer */ if (stream) { if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL TSRMLS_CC) < 0 || php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy"); php_stream_close(stream); stream = NULL; } } } if (stream == NULL) goto out; /* avoid buffering issues while reading header */ if (options & STREAM_WILL_CAST) chunk_size = php_stream_set_chunk_size(stream, 1); /* avoid problems with auto-detecting when reading the headers -> the headers * are always in canonical \r\n format */ eol_detect = stream->flags & (PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC); stream->flags &= ~(PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC); php_stream_context_set(stream, context); php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0); if (header_init && context && php_stream_context_get_option(context, "http", "max_redirects", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); redirect_max = Z_LVAL_PP(tmpzval); } if (context && php_stream_context_get_option(context, "http", "method", &tmpzval) == SUCCESS) { if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) { /* As per the RFC, automatically redirected requests MUST NOT use other methods than * GET and HEAD unless it can be confirmed by the user */ if (!redirected || (Z_STRLEN_PP(tmpzval) == 3 && memcmp("GET", Z_STRVAL_PP(tmpzval), 3) == 0) || (Z_STRLEN_PP(tmpzval) == 4 && memcmp("HEAD",Z_STRVAL_PP(tmpzval), 4) == 0) ) { scratch_len = strlen(path) + 29 + Z_STRLEN_PP(tmpzval); scratch = emalloc(scratch_len); strlcpy(scratch, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) + 1); strncat(scratch, " ", 1); } } } if (context && php_stream_context_get_option(context, "http", "protocol_version", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_double_ex(tmpzval); protocol_version_len = spprintf(&protocol_version, 0, "%.1F", Z_DVAL_PP(tmpzval)); } if (!scratch) { scratch_len = strlen(path) + 29 + protocol_version_len; scratch = emalloc(scratch_len); strncpy(scratch, "GET ", scratch_len); } /* Should we send the entire path in the request line, default to no. */ if (!request_fulluri && context && php_stream_context_get_option(context, "http", "request_fulluri", &tmpzval) == SUCCESS) { zval ztmp = **tmpzval; zval_copy_ctor(&ztmp); convert_to_boolean(&ztmp); request_fulluri = Z_BVAL(ztmp) ? 1 : 0; zval_dtor(&ztmp); } if (request_fulluri) { /* Ask for everything */ strcat(scratch, path); } else { /* Send the traditional /path/to/file?query_string */ /* file */ if (resource->path && *resource->path) { strlcat(scratch, resource->path, scratch_len); } else { strlcat(scratch, "/", scratch_len); } /* query string */ if (resource->query) { strlcat(scratch, "?", scratch_len); strlcat(scratch, resource->query, scratch_len); } } /* protocol version we are speaking */ if (protocol_version) { strlcat(scratch, " HTTP/", scratch_len); strlcat(scratch, protocol_version, scratch_len); strlcat(scratch, "\r\n", scratch_len); efree(protocol_version); protocol_version = NULL; } else { strlcat(scratch, " HTTP/1.0\r\n", scratch_len); } /* send it */ php_stream_write(stream, scratch, strlen(scratch)); if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) { tmp = NULL; if (Z_TYPE_PP(tmpzval) == IS_ARRAY) { HashPosition pos; zval **tmpheader = NULL; smart_str tmpstr = {0}; for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos); SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos); zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos) ) { if (Z_TYPE_PP(tmpheader) == IS_STRING) { smart_str_appendl(&tmpstr, Z_STRVAL_PP(tmpheader), Z_STRLEN_PP(tmpheader)); smart_str_appendl(&tmpstr, "\r\n", sizeof("\r\n") - 1); } } smart_str_0(&tmpstr); /* Remove newlines and spaces from start and end. there's at least one extra \r\n at the end that needs to go. */ if (tmpstr.c) { tmp = php_trim(tmpstr.c, strlen(tmpstr.c), NULL, 0, NULL, 3 TSRMLS_CC); smart_str_free(&tmpstr); } } if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) { /* Remove newlines and spaces from start and end php_trim will estrndup() */ tmp = php_trim(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), NULL, 0, NULL, 3 TSRMLS_CC); } if (tmp && strlen(tmp) > 0) { char *s; if (!header_init) { /* Remove post headers for redirects */ int l = strlen(tmp); char *s2, *tmp_c = estrdup(tmp); php_strtolower(tmp_c, l); if ((s = strstr(tmp_c, "content-length:"))) { if ((s2 = memchr(s, '\n', tmp_c + l - s))) { int b = tmp_c + l - 1 - s2; memmove(tmp, tmp + (s2 + 1 - tmp_c), b); memmove(tmp_c, s2 + 1, b); } else { tmp[s - tmp_c] = *s = '\0'; } l = strlen(tmp_c); } if ((s = strstr(tmp_c, "content-type:"))) { if ((s2 = memchr(s, '\n', tmp_c + l - s))) { memmove(tmp, tmp + (s2 + 1 - tmp_c), tmp_c + l - 1 - s2); } else { tmp[s - tmp_c] = '\0'; } } efree(tmp_c); tmp_c = php_trim(tmp, strlen(tmp), NULL, 0, NULL, 3 TSRMLS_CC); efree(tmp); tmp = tmp_c; } user_headers = estrdup(tmp); /* Make lowercase for easy comparison against 'standard' headers */ php_strtolower(tmp, strlen(tmp)); if ((s = strstr(tmp, "user-agent:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_USER_AGENT; } if ((s = strstr(tmp, "host:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_HOST; } if ((s = strstr(tmp, "from:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_FROM; } if ((s = strstr(tmp, "authorization:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_AUTH; } if ((s = strstr(tmp, "content-length:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_CONTENT_LENGTH; } if ((s = strstr(tmp, "content-type:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_TYPE; } /* remove Proxy-Authorization header */ if (use_proxy && use_ssl && (s = strstr(tmp, "proxy-authorization:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { char *p = s + sizeof("proxy-authorization:") - 1; while (s > tmp && (*(s-1) == ' ' || *(s-1) == '\t')) s--; while (*p != 0 && *p != '\r' && *p != '\n') p++; while (*p == '\r' || *p == '\n') p++; if (*p == 0) { if (s == tmp) { efree(user_headers); user_headers = NULL; } else { while (s > tmp && (*(s-1) == '\r' || *(s-1) == '\n')) s--; user_headers[s - tmp] = 0; } } else { memmove(user_headers + (s - tmp), user_headers + (p - tmp), strlen(p) + 1); } } } if (tmp) { efree(tmp); } } /* auth header if it was specified */ if (((have_header & HTTP_HEADER_AUTH) == 0) && resource->user) { /* decode the strings first */ php_url_decode(resource->user, strlen(resource->user)); /* scratch is large enough, since it was made large enough for the whole URL */ strcpy(scratch, resource->user); strcat(scratch, ":"); /* Note: password is optional! */ if (resource->pass) { php_url_decode(resource->pass, strlen(resource->pass)); strcat(scratch, resource->pass); } tmp = (char*)php_base64_encode((unsigned char*)scratch, strlen(scratch), NULL); if (snprintf(scratch, scratch_len, "Authorization: Basic %s\r\n", tmp) > 0) { php_stream_write(stream, scratch, strlen(scratch)); php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0); } efree(tmp); tmp = NULL; } /* if the user has configured who they are, send a From: line */ { char *from_address = php_ini_string("from", sizeof("from"), 0); if (((have_header & HTTP_HEADER_FROM) == 0) && from_address && from_address[0] != '\0') { if (snprintf(scratch, scratch_len, "From: %s\r\n", from_address) > 0) php_stream_write(stream, scratch, strlen(scratch)); } } /* Send Host: header so name-based virtual hosts work */ if ((have_header & HTTP_HEADER_HOST) == 0) { if ((use_ssl && resource->port != 443 && resource->port != 0) || (!use_ssl && resource->port != 80 && resource->port != 0)) { if (snprintf(scratch, scratch_len, "Host: %s:%i\r\n", resource->host, resource->port) > 0) php_stream_write(stream, scratch, strlen(scratch)); } else { if (snprintf(scratch, scratch_len, "Host: %s\r\n", resource->host) > 0) { php_stream_write(stream, scratch, strlen(scratch)); } } } if (context && php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS && Z_TYPE_PP(ua_zval) == IS_STRING) { ua_str = Z_STRVAL_PP(ua_zval); } else if (FG(user_agent)) { ua_str = FG(user_agent); } if (((have_header & HTTP_HEADER_USER_AGENT) == 0) && ua_str) { #define _UA_HEADER "User-Agent: %s\r\n" char *ua; size_t ua_len; ua_len = sizeof(_UA_HEADER) + strlen(ua_str); /* ensure the header is only sent if user_agent is not blank */ if (ua_len > sizeof(_UA_HEADER)) { ua = emalloc(ua_len + 1); if ((ua_len = slprintf(ua, ua_len, _UA_HEADER, ua_str)) > 0) { ua[ua_len] = 0; php_stream_write(stream, ua, ua_len); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot construct User-agent header"); } if (ua) { efree(ua); } } } if (user_headers) { /* A bit weird, but some servers require that Content-Length be sent prior to Content-Type for POST * see bug #44603 for details. Since Content-Type maybe part of user's headers we need to do this check first. */ if ( header_init && context && !(have_header & HTTP_HEADER_CONTENT_LENGTH) && php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS && Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0 ) { scratch_len = slprintf(scratch, scratch_len, "Content-Length: %d\r\n", Z_STRLEN_PP(tmpzval)); php_stream_write(stream, scratch, scratch_len); have_header |= HTTP_HEADER_CONTENT_LENGTH; } php_stream_write(stream, user_headers, strlen(user_headers)); php_stream_write(stream, "\r\n", sizeof("\r\n")-1); efree(user_headers); } /* Request content, such as for POST requests */ if (header_init && context && php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS && Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) { if (!(have_header & HTTP_HEADER_CONTENT_LENGTH)) { scratch_len = slprintf(scratch, scratch_len, "Content-Length: %d\r\n", Z_STRLEN_PP(tmpzval)); php_stream_write(stream, scratch, scratch_len); } if (!(have_header & HTTP_HEADER_TYPE)) { php_stream_write(stream, "Content-Type: application/x-www-form-urlencoded\r\n", sizeof("Content-Type: application/x-www-form-urlencoded\r\n") - 1); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Content-type not specified assuming application/x-www-form-urlencoded"); } php_stream_write(stream, "\r\n", sizeof("\r\n")-1); php_stream_write(stream, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval)); } else { php_stream_write(stream, "\r\n", sizeof("\r\n")-1); } location[0] = '\0'; if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); } if (header_init) { zval *ztmp; MAKE_STD_ZVAL(ztmp); array_init(ztmp); ZEND_SET_SYMBOL(EG(active_symbol_table), "http_response_header", ztmp); } { zval **rh; zend_hash_find(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &rh); response_header = *rh; } if (!php_stream_eof(stream)) { size_t tmp_line_len; /* get response header */ if (php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) { zval *http_response; int response_code; if (tmp_line_len > 9) { response_code = atoi(tmp_line + 9); } else { response_code = 0; } if (context && SUCCESS==php_stream_context_get_option(context, "http", "ignore_errors", &tmpzval)) { ignore_errors = zend_is_true(*tmpzval); } /* when we request only the header, don't fail even on error codes */ if ((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) { reqok = 1; } /* all status codes in the 2xx range are defined by the specification as successful; * all status codes in the 3xx range are for redirection, and so also should never * fail */ if (response_code >= 200 && response_code < 400) { reqok = 1; } else { switch(response_code) { case 403: php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT, tmp_line, response_code); break; default: /* safety net in the event tmp_line == NULL */ if (!tmp_line_len) { tmp_line[0] = '\0'; } php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, tmp_line, response_code); } } if (tmp_line[tmp_line_len - 1] == '\n') { --tmp_line_len; if (tmp_line[tmp_line_len - 1] == '\r') { --tmp_line_len; } } MAKE_STD_ZVAL(http_response); ZVAL_STRINGL(http_response, tmp_line, tmp_line_len, 1); zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_response, sizeof(zval *), NULL); } } else { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed, unexpected end of socket!"); goto out; } /* read past HTTP headers */ http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE); while (!body && !php_stream_eof(stream)) { size_t http_header_line_length; if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') { char *e = http_header_line + http_header_line_length - 1; if (*e != '\n') { do { /* partial header */ if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) == NULL) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Failed to read HTTP headers"); goto out; } e = http_header_line + http_header_line_length - 1; } while (*e != '\n'); continue; } while (*e == '\n' || *e == '\r') { e--; } http_header_line_length = e - http_header_line + 1; http_header_line[http_header_line_length] = '\0'; if (!strncasecmp(http_header_line, "Location: ", 10)) { if (context && php_stream_context_get_option(context, "http", "follow_location", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); follow_location = Z_LVAL_PP(tmpzval); } strlcpy(location, http_header_line + 10, sizeof(location)); } else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) { php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0); } else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) { file_size = atoi(http_header_line + 16); php_stream_notify_file_size(context, file_size, http_header_line, 0); } else if (!strncasecmp(http_header_line, "Transfer-Encoding: chunked", sizeof("Transfer-Encoding: chunked"))) { /* create filter to decode response body */ if (!(options & STREAM_ONLY_GET_HEADERS)) { long decode = 1; if (context && php_stream_context_get_option(context, "http", "auto_decode", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_boolean(*tmpzval); decode = Z_LVAL_PP(tmpzval); } if (decode) { transfer_encoding = php_stream_filter_create("dechunk", NULL, php_stream_is_persistent(stream) TSRMLS_CC); if (transfer_encoding) { /* don't store transfer-encodeing header */ continue; } } } } if (http_header_line[0] == '\0') { body = 1; } else { zval *http_header; MAKE_STD_ZVAL(http_header); ZVAL_STRINGL(http_header, http_header_line, http_header_line_length, 1); zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header, sizeof(zval *), NULL); } } else { break; } } if (!reqok || (location[0] != '\0' && follow_location)) { if (!follow_location || (((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) && redirect_max <= 1)) { goto out; } if (location[0] != '\0') php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, location, 0); php_stream_close(stream); stream = NULL; if (location[0] != '\0') { char new_path[HTTP_HEADER_BLOCK_SIZE]; char loc_path[HTTP_HEADER_BLOCK_SIZE]; *new_path='\0'; if (strlen(location)<8 || (strncasecmp(location, "http://", sizeof("http://")-1) && strncasecmp(location, "https://", sizeof("https://")-1) && strncasecmp(location, "ftp://", sizeof("ftp://")-1) && strncasecmp(location, "ftps://", sizeof("ftps://")-1))) { if (*location != '/') { if (*(location+1) != '\0' && resource->path) { char *s = strrchr(resource->path, '/'); if (!s) { s = resource->path; if (!s[0]) { efree(s); s = resource->path = estrdup("/"); } else { *s = '/'; } } s[1] = '\0'; if (resource->path && *(resource->path) == '/' && *(resource->path + 1) == '\0') { snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", resource->path, location); } else { snprintf(loc_path, sizeof(loc_path) - 1, "%s/%s", resource->path, location); } } else { snprintf(loc_path, sizeof(loc_path) - 1, "/%s", location); } } else { strlcpy(loc_path, location, sizeof(loc_path)); } if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) { snprintf(new_path, sizeof(new_path) - 1, "%s://%s:%d%s", resource->scheme, resource->host, resource->port, loc_path); } else { snprintf(new_path, sizeof(new_path) - 1, "%s://%s%s", resource->scheme, resource->host, loc_path); } } else { strlcpy(new_path, location, sizeof(new_path)); } php_url_free(resource); /* check for invalid redirection URLs */ if ((resource = php_url_parse(new_path)) == NULL) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect URL! %s", new_path); goto out; } #define CHECK_FOR_CNTRL_CHARS(val) { \ if (val) { \ unsigned char *s, *e; \ int l; \ l = php_url_decode(val, strlen(val)); \ s = (unsigned char*)val; e = s + l; \ while (s < e) { \ if (iscntrl(*s)) { \ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect URL! %s", new_path); \ goto out; \ } \ s++; \ } \ } \ } /* check for control characters in login, password & path */ if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) { CHECK_FOR_CNTRL_CHARS(resource->user) CHECK_FOR_CNTRL_CHARS(resource->pass) CHECK_FOR_CNTRL_CHARS(resource->path) } stream = php_stream_url_wrap_http_ex(wrapper, new_path, mode, options, opened_path, context, --redirect_max, HTTP_WRAPPER_REDIRECTED STREAMS_CC TSRMLS_CC); } else {
/** * Restore a memory stack applying GC to all observed variables */ static void zephir_memory_restore_stack_common(zend_zephir_globals_def *g) { size_t i; zephir_memory_entry *prev, *active_memory; zephir_symbol_table *active_symbol_table; zval *ptr; active_memory = g->active_memory; assert(active_memory != NULL); if (EXPECTED(!CG(unclean_shutdown))) { /* Clean active symbol table */ if (g->active_symbol_table) { active_symbol_table = g->active_symbol_table; if (active_symbol_table->scope == active_memory) { zend_hash_destroy(EG(current_execute_data)->symbol_table); FREE_HASHTABLE(EG(current_execute_data)->symbol_table); EG(current_execute_data)->symbol_table = active_symbol_table->symbol_table; g->active_symbol_table = active_symbol_table->prev; efree(active_symbol_table); } } /* Check for non freed hash key zvals, mark as null to avoid string freeing */ for (i = 0; i < active_memory->hash_pointer; ++i) { assert(active_memory->hash_addresses[i] != NULL); if (!Z_REFCOUNTED_P(active_memory->hash_addresses[i])) continue; if (Z_REFCOUNT_P(active_memory->hash_addresses[i]) <= 1) { ZVAL_NULL(active_memory->hash_addresses[i]); } else { zval_copy_ctor(active_memory->hash_addresses[i]); } } #ifndef ZEPHIR_RELEASE for (i = 0; i < active_memory->pointer; ++i) { if (active_memory->addresses[i] != NULL) { zval *var = active_memory->addresses[i]; if (Z_TYPE_P(var) > IS_CALLABLE) { fprintf(stderr, "%s: observed variable #%d (%p) has invalid type %u [%s]\n", __func__, (int)i, var, Z_TYPE_P(var), active_memory->func); } if (!Z_REFCOUNTED_P(var)) continue; if (Z_REFCOUNT_P(var) == 0) { fprintf(stderr, "%s: observed variable #%d (%p) has 0 references, type=%d [%s]\n", __func__, (int)i, var, Z_TYPE_P(var), active_memory->func); } else if (Z_REFCOUNT_P(var) >= 1000000) { fprintf(stderr, "%s: observed variable #%d (%p) has too many references (%u), type=%d [%s]\n", __func__, (int)i, var, Z_REFCOUNT_P(var), Z_TYPE_P(var), active_memory->func); } #if 0 /* Skip this check, PDO does return variables with is_ref = 1 and refcount = 1*/ else if (Z_REFCOUNT_PP(var) == 1 && Z_ISREF_PP(var)) { fprintf(stderr, "%s: observed variable #%d (%p) is a reference with reference count = 1, type=%d [%s]\n", __func__, (int)i, *var, Z_TYPE_PP(var), active_memory->func); } #endif } } #endif /* Traverse all zvals allocated, reduce the reference counting or free them */ for (i = 0; i < active_memory->pointer; ++i) { ptr = active_memory->addresses[i]; if (EXPECTED(ptr != NULL)) { if (!Z_REFCOUNTED_P(ptr)) continue; if (Z_REFCOUNT_P(ptr) == 1) { zval_ptr_dtor(ptr); } else { Z_DELREF_P(ptr); } } } } #ifndef ZEPHIR_RELEASE active_memory->func = NULL; #endif prev = active_memory->prev; if (active_memory >= g->end_memory || active_memory < g->start_memory) { #ifndef ZEPHIR_RELEASE assert(g->active_memory->permanent == 0); #endif assert(prev != NULL); if (active_memory->hash_addresses != NULL) { efree(active_memory->hash_addresses); } if (active_memory->addresses != NULL) { efree(active_memory->addresses); } efree(g->active_memory); g->active_memory = prev; prev->next = NULL; } else { #ifndef ZEPHIR_RELEASE assert(g->active_memory->permanent == 1); #endif active_memory->pointer = 0; active_memory->hash_pointer = 0; g->active_memory = prev; } #ifndef ZEPHIR_RELEASE if (g->active_memory) { zephir_memory_entry *f = g->active_memory; if (f >= g->start_memory && f < g->end_memory - 1) { assert(f->permanent == 1); assert(f->next != NULL); if (f > g->start_memory) { assert(f->prev != NULL); } } } #endif }
PHP_COUCHBASE_LOCAL void php_couchbase_get_impl(INTERNAL_FUNCTION_PARAMETERS, int multi, int oo, int lock, int touch) { char *key, **keys; long *klens, klen = 0; int nkey = 0; long flag = 0; lcb_time_t exp = {0}; long expiry = 0; zval *res, *cas_token = NULL; int argflags; lcb_error_t retval; php_couchbase_res *couchbase_res; php_couchbase_ctx *ctx; argflags = oo ? PHP_COUCHBASE_ARG_F_OO : PHP_COUCHBASE_ARG_F_FUNCTIONAL; if (multi) { zval *akeys; zval **ppzval; zend_bool preserve_order; int i; if (lock) { PHP_COUCHBASE_GET_PARAMS_WITH_ZV(res, couchbase_res, argflags, "az|ll", &akeys, &cas_token, &flag, &expiry); } else if (touch) { PHP_COUCHBASE_GET_PARAMS_WITH_ZV(res, couchbase_res, argflags, "al|z", &akeys, &expiry, &cas_token); } else { PHP_COUCHBASE_GET_PARAMS_WITH_ZV(res, couchbase_res, argflags, "a|zl", &akeys, &cas_token, &flag); } nkey = zend_hash_num_elements(Z_ARRVAL_P(akeys)); keys = ecalloc(nkey, sizeof(char *)); klens = ecalloc(nkey, sizeof(long)); preserve_order = (flag & COUCHBASE_GET_PRESERVE_ORDER); array_init(return_value); for (i = 0, zend_hash_internal_pointer_reset(Z_ARRVAL_P(akeys)); zend_hash_has_more_elements(Z_ARRVAL_P(akeys)) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(akeys)), i++) { if (zend_hash_get_current_data(Z_ARRVAL_P(akeys), (void **)&ppzval) == FAILURE) { nkey--; continue; } if (IS_ARRAY != Z_TYPE_PP(ppzval)) { convert_to_string_ex(ppzval); } if (!Z_STRLEN_PP(ppzval)) { nkey--; continue; } if (couchbase_res->prefix_key_len) { klens[i] = spprintf(&(keys[i]), 0, "%s_%s", couchbase_res->prefix_key, Z_STRVAL_PP(ppzval)); } else { keys[i] = Z_STRVAL_PP(ppzval); klens[i] = Z_STRLEN_PP(ppzval); } if (preserve_order) { add_assoc_null_ex(return_value, keys[i], klens[i] + 1); } } if (!nkey) { efree(keys); efree(klens); return; } if (cas_token && IS_ARRAY != Z_TYPE_P(cas_token)) { zval_dtor(cas_token); array_init(cas_token); } } else { if (lock) { PHP_COUCHBASE_GET_PARAMS_WITH_ZV(res, couchbase_res, argflags, "sz|l", &key, &klen, &cas_token, &expiry); } else if (touch) { PHP_COUCHBASE_GET_PARAMS_WITH_ZV(res, couchbase_res, argflags, "sl|z", &key, &klen, &expiry, &cas_token); } else { PHP_COUCHBASE_GET_PARAMS_WITH_ZV(res, couchbase_res, argflags, "s|z", &key, &klen, &cas_token); } if (!klen) { return; } nkey = 1; if (couchbase_res->prefix_key_len) { klen = spprintf(&key, 0, "%s_%s", couchbase_res->prefix_key, key); } keys = &key; klens = &klen; if (cas_token) { zval_dtor(cas_token); ZVAL_NULL(cas_token); } } { lcb_get_cmd_t **commands = ecalloc(nkey, sizeof(lcb_get_cmd_t *)); int ii; if (expiry) { exp = pcbc_check_expiry(expiry); } for (ii = 0; ii < nkey; ++ii) { lcb_get_cmd_t *cmd = ecalloc(1, sizeof(lcb_get_cmd_t)); commands[ii] = cmd; cmd->v.v0.key = keys[ii]; cmd->v.v0.nkey = klens[ii]; cmd->v.v0.lock = (int)lock; cmd->v.v0.exptime = exp; /* NB: this assumes sizeof(lcb_time_t) == sizeof(long) */ } ctx = ecalloc(1, sizeof(php_couchbase_ctx)); ctx->res = couchbase_res; ctx->rv = return_value; ctx->cas = cas_token; retval = lcb_get(couchbase_res->handle, ctx, nkey, (const lcb_get_cmd_t * const *)commands); for (ii = 0; ii < nkey; ++ii) { efree(commands[ii]); } efree(commands); if (LCB_SUCCESS != retval) { if (couchbase_res->prefix_key_len) { int i; for (i = 0; i < nkey; i++) { efree(keys[i]); } } if (multi) { efree(keys); efree(klens); zval_dtor(return_value); } efree(ctx); couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo, cb_lcb_exception, "Failed to schedule get request: %s", lcb_strerror(couchbase_res->handle, retval)); return; } couchbase_res->seqno += nkey; pcbc_start_loop(couchbase_res); if (LCB_SUCCESS != ctx->res->rc) { if (LCB_KEY_ENOENT != ctx->res->rc) { couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo, cb_lcb_exception, "Failed to get a value from server: %s", lcb_strerror(couchbase_res->handle, ctx->res->rc)); } } efree(ctx); if (couchbase_res->prefix_key_len) { int i; for (i = 0; i < nkey; i++) { efree(keys[i]); } } if (multi) { efree(keys); efree(klens); } } }
U_CFUNC PHP_FUNCTION(intlcal_from_date_time) { zval **zv_arg, *zv_datetime = NULL; double millis; php_date_obj *datetime; char *locale_str = NULL; int locale_str_len; TimeZone *timeZone; UErrorCode status = U_ZERO_ERROR; Calendar *cal; intl_error_reset(NULL TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|s!", &zv_arg, &locale_str, &locale_str_len) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_from_date_time: bad arguments", 0 TSRMLS_CC); RETURN_NULL(); } if (!(Z_TYPE_PP(zv_arg) == IS_OBJECT && instanceof_function( Z_OBJCE_PP(zv_arg), php_date_get_date_ce() TSRMLS_CC))) { ALLOC_INIT_ZVAL(zv_datetime); object_init_ex(zv_datetime, php_date_get_date_ce()); zend_call_method_with_1_params(&zv_datetime, NULL, NULL, "__construct", NULL, *zv_arg); if (EG(exception)) { zend_object_store_ctor_failed(zv_datetime TSRMLS_CC); goto error; } } else { zv_datetime = *zv_arg; } datetime = (php_date_obj*)zend_object_store_get_object(zv_datetime TSRMLS_CC); if (!datetime->time) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_from_date_time: DateTime object is unconstructed", 0 TSRMLS_CC); goto error; } if (intl_datetime_decompose(zv_datetime, &millis, NULL, NULL, "intlcal_from_date_time" TSRMLS_CC) == FAILURE) { goto error; } if (!datetime->time->is_localtime) { timeZone = TimeZone::getGMT()->clone(); } else { timeZone = timezone_convert_datetimezone(datetime->time->zone_type, datetime, 1, NULL, "intlcal_from_date_time" TSRMLS_CC); if (timeZone == NULL) { goto error; } } if (!locale_str) { locale_str = const_cast<char*>(intl_locale_get_default(TSRMLS_C)); } cal = Calendar::createInstance(timeZone, Locale::createFromName(locale_str), status); if (cal == NULL) { delete timeZone; intl_error_set(NULL, status, "intlcal_from_date_time: " "error creating ICU Calendar object", 0 TSRMLS_CC); goto error; } cal->setTime(millis, status); if (U_FAILURE(status)) { /* time zone was adopted by cal; should not be deleted here */ delete cal; intl_error_set(NULL, status, "intlcal_from_date_time: " "error creating ICU Calendar::setTime()", 0 TSRMLS_CC); goto error; } calendar_object_create(return_value, cal TSRMLS_CC); error: if (zv_datetime != *zv_arg) { zval_ptr_dtor(&zv_datetime); } }
void zephir_concat_svsvsvs(zval **result, const char *op1, zend_uint op1_len, zval *op2, const char *op3, zend_uint op3_len, zval *op4, const char *op5, zend_uint op5_len, zval *op6, const char *op7, zend_uint op7_len, int self_var TSRMLS_DC){ zval result_copy, op2_copy, op4_copy, op6_copy; int use_copy = 0, use_copy2 = 0, use_copy4 = 0, use_copy6 = 0; uint offset = 0, length; if (Z_TYPE_P(op2) != IS_STRING) { zend_make_printable_zval(op2, &op2_copy, &use_copy2); if (use_copy2) { op2 = &op2_copy; } } if (Z_TYPE_P(op4) != IS_STRING) { zend_make_printable_zval(op4, &op4_copy, &use_copy4); if (use_copy4) { op4 = &op4_copy; } } if (Z_TYPE_P(op6) != IS_STRING) { zend_make_printable_zval(op6, &op6_copy, &use_copy6); if (use_copy6) { op6 = &op6_copy; } } length = op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4) + op5_len + Z_STRLEN_P(op6) + op7_len; if (self_var) { if (Z_TYPE_PP(result) != IS_STRING) { zend_make_printable_zval(*result, &result_copy, &use_copy); if (use_copy) { ZEPHIR_CPY_WRT_CTOR(*result, (&result_copy)); } } offset = Z_STRLEN_PP(result); length += offset; Z_STRVAL_PP(result) = (char *) str_erealloc(Z_STRVAL_PP(result), length + 1); } else { Z_STRVAL_PP(result) = (char *) emalloc(length + 1); } memcpy(Z_STRVAL_PP(result) + offset, op1, op1_len); memcpy(Z_STRVAL_PP(result) + offset + op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2)); memcpy(Z_STRVAL_PP(result) + offset + op1_len + Z_STRLEN_P(op2), op3, op3_len); memcpy(Z_STRVAL_PP(result) + offset + op1_len + Z_STRLEN_P(op2) + op3_len, Z_STRVAL_P(op4), Z_STRLEN_P(op4)); memcpy(Z_STRVAL_PP(result) + offset + op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4), op5, op5_len); memcpy(Z_STRVAL_PP(result) + offset + op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4) + op5_len, Z_STRVAL_P(op6), Z_STRLEN_P(op6)); memcpy(Z_STRVAL_PP(result) + offset + op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4) + op5_len + Z_STRLEN_P(op6), op7, op7_len); Z_STRVAL_PP(result)[length] = 0; Z_TYPE_PP(result) = IS_STRING; Z_STRLEN_PP(result) = length; if (use_copy2) { zval_dtor(op2); } if (use_copy4) { zval_dtor(op4); } if (use_copy6) { zval_dtor(op6); } if (use_copy) { zval_dtor(&result_copy); } }
static zval *get_trace_detail(const jsonlite_decoder *self) { HashTable *array = NULL; HashPosition *pointer = NULL; zval *traces = NULL; zval *trace = NULL; zval **val = NULL; zval **msg = NULL; zval **range_start = NULL; zval **range_end = NULL; zval *range = NULL; char *str = NULL; zval *chars = NULL; zval **detail = NULL; int start = 0; int end = 0; array = Z_ARRVAL_P(self->trace); ALLOC_INIT_ZVAL(traces); array_init(traces); zend_hash_internal_pointer_reset_ex(array, pointer); while (zend_hash_has_more_elements_ex(array, pointer) == SUCCESS) { if (zend_hash_get_current_data_ex(array, (void **) &val, pointer) == SUCCESS) { if (val && Z_TYPE_PP(val) == IS_ARRAY) { zend_hash_index_find(Z_ARRVAL_PP(val), 0, (void **) &msg); zend_hash_index_find(Z_ARRVAL_PP(val), 1, (void **) &range_start); zend_hash_index_find(Z_ARRVAL_PP(val), 2, (void **) &range_end); if (zend_hash_index_exists(Z_ARRVAL_PP(val), 3) == 1) { zend_hash_index_find(Z_ARRVAL_PP(val), 3, (void **) &detail); } ALLOC_INIT_ZVAL(trace); array_init(trace); zval_add_ref(msg); add_assoc_zval_ex(trace, ZEND_STRS("msg"), *msg); ALLOC_INIT_ZVAL(range); array_init(range); zval_add_ref(range_start); add_next_index_zval(range, *range_start); zval_add_ref(range_end); add_next_index_zval(range, *range_end); add_assoc_zval_ex(trace, ZEND_STRS("range"), range); start = Z_LVAL_PP(range_start); if (start > 0) { start--; } end = Z_LVAL_PP(range_end); if (end < self->length) { end++; } str = zend_strndup((self->jsonlite + start), end - start); add_assoc_string_ex(trace, ZEND_STRS("chars"), str, 1); free(str); if (detail != NULL) { zval_add_ref(detail); add_assoc_zval_ex(trace, ZEND_STRS("detail"), *detail); } add_next_index_zval(traces, trace); detail = NULL; trace = NULL; } } if (zend_hash_move_forward_ex(array, pointer) == FAILURE) { break; } } return traces; }
zval *phalcon_replace_marker(int named, zval *paths, zval *replacements, unsigned long *position, char *cursor, char *marker){ zval **zv, **tmp; int result = FAILURE; unsigned int length = 0, variable_length, ch, j; char *item = NULL, *cursor_var, *variable = NULL; int not_valid = 0; if (named) { length = cursor - marker - 1; item = estrndup(marker + 1, length); cursor_var = item; marker = item; for (j = 0; j < length; j++) { ch = *cursor_var; if (ch == '\0') { not_valid = 1; break; } if (j == 0 && !((ch >= 'a' && ch <='z') || (ch >= 'A' && ch <= 'Z'))){ not_valid = 1; break; } if ((ch >= 'a' && ch <='z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '-' || ch == '_' || ch == ':') { if (ch == ':') { variable_length = cursor_var - marker; variable = estrndup(marker, variable_length); break; } } else { not_valid = 1; break; } cursor_var++; } } if (!not_valid) { if (zend_hash_index_exists(Z_ARRVAL_P(paths), *position)) { if (named) { if (variable) { efree(item); item = variable; length = variable_length; } if (zend_hash_exists(Z_ARRVAL_P(replacements), item, length + 1)) { if ((result = zend_hash_find(Z_ARRVAL_P(replacements), item, length + 1, (void**) &zv)) == SUCCESS) { efree(item); (*position)++; return *zv; } } } else { if ((result = zend_hash_index_find(Z_ARRVAL_P(paths), *position, (void**) &zv)) == SUCCESS) { if (Z_TYPE_PP(zv) == IS_STRING) { if (zend_hash_exists(Z_ARRVAL_P(replacements), Z_STRVAL_PP(zv), Z_STRLEN_PP(zv) + 1)) { if ((result = zend_hash_find(Z_ARRVAL_P(replacements), Z_STRVAL_PP(zv), Z_STRLEN_PP(zv) + 1, (void**) &tmp)) == SUCCESS) { (*position)++; return *tmp; } } } } } } (*position)++; } if (item) { efree(item); } return NULL; }
PHP_COUCHBASE_LOCAL void php_couchbase_touch_multi_impl(INTERNAL_FUNCTION_PARAMETERS, int oo) { int argflags; int idx = 0; int ii; lcb_error_t retval; lcb_t instance; lcb_time_t exp = 0; lcb_touch_cmd_t **commands; lcb_touch_cmd_t *cmd; long expiry; php_couchbase_res *couchbase_res; struct multi_touch_cookie cookie; zval **ppzval; zval *arr_keys; /* parameter handling and return_value setup: */ if (oo) { argflags = PHP_COUCHBASE_ARG_F_OO; } else { argflags = PHP_COUCHBASE_ARG_F_FUNCTIONAL; } PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags, "al", &arr_keys, &expiry); instance = couchbase_res->handle; memset(&cookie, 0, sizeof(cookie)); cookie.nkeys = zend_hash_num_elements(Z_ARRVAL_P(arr_keys)); cookie.keys = ecalloc(cookie.nkeys, sizeof(struct touch_cookie)); for (ii = 0, zend_hash_internal_pointer_reset(Z_ARRVAL_P(arr_keys)); zend_hash_has_more_elements(Z_ARRVAL_P(arr_keys)) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(arr_keys)), ii++) { if (zend_hash_get_current_data(Z_ARRVAL_P(arr_keys), (void **)&ppzval) == FAILURE) { continue; } if (IS_ARRAY != Z_TYPE_PP(ppzval)) { convert_to_string_ex(ppzval); } if (!Z_STRLEN_PP(ppzval)) { continue; } if (couchbase_res->prefix_key_len) { cookie.keys[idx].nkey = spprintf(&(cookie.keys[idx].key), 0, "%s_%s", couchbase_res->prefix_key, Z_STRVAL_PP(ppzval)); } else { cookie.keys[idx].key = Z_STRVAL_PP(ppzval); cookie.keys[idx].nkey = Z_STRLEN_PP(ppzval); } ++idx; } if (idx == 0) { efree(cookie.keys); couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo, cb_illegal_key_exception, "No keys specified"); return; } if (expiry) { exp = pcbc_check_expiry(expiry); } cmd = ecalloc(idx, sizeof(lcb_touch_cmd_t)); commands = ecalloc(idx, sizeof(lcb_touch_cmd_t *)); for (ii = 0; ii < idx; ++ii) { cmd[ii].v.v0.key = cookie.keys[ii].key; cmd[ii].v.v0.nkey = cookie.keys[ii].nkey; cmd[ii].v.v0.exptime = exp; commands[ii] = cmd + ii; } lcb_set_touch_callback(instance, multi_touch_callback); lcb_behavior_set_syncmode(instance, LCB_SYNCHRONOUS); retval = lcb_touch(instance, &cookie, idx, (const lcb_touch_cmd_t * const *)commands); lcb_behavior_set_syncmode(instance, LCB_ASYNCHRONOUS); if (retval == LCB_SUCCESS) { retval = cookie.error; } couchbase_res->rc = retval; if (retval == LCB_SUCCESS) { /* Time to build up the array with the keys we found etc */ array_init(return_value); for (ii = 0; ii < idx; ++ii) { char *k = cookie.keys[ii].key; if (cookie.keys[ii].error == LCB_SUCCESS) { char cas[80]; snprintf(cas, sizeof(cas), "%llu", (unsigned long long)cookie.keys[ii].cas); add_assoc_string(return_value, k, cas, 1); } else { add_assoc_bool(return_value, k, (zend_bool)0); } } } else { couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo, cb_lcb_exception, "Failed to touch key: %s", lcb_strerror(instance, retval)); } /* Release allocated memory */ efree(cmd); efree(commands); if (couchbase_res->prefix_key_len) { for (ii = 0; ii < idx; ++ii) { efree(cookie.keys[ii].key); } } efree(cookie.keys); }
int mongo_util_server_ping(mongo_server *server, time_t now TSRMLS_DC) { server_info* info; zval *response = 0, **secondary = 0, **bson = 0, **self = 0; struct timeval start, end; if ((info = mongo_util_server__get_info(server TSRMLS_CC)) == 0) { return FAILURE; } if (info->guts->last_ping + MONGO_PING_INTERVAL > now) { return info->guts->master ? SUCCESS : FAILURE; } gettimeofday(&start, 0); response = mongo_util_rs__ismaster(server TSRMLS_CC); gettimeofday(&end, 0); mongo_util_server__set_ping(info, start, end); if (!response) { return FAILURE; } zend_hash_find(HASH_P(response), "me", strlen("me")+1, (void**)&self); if (!info->guts->pinged && self && strncmp(Z_STRVAL_PP(self), server->label, Z_STRLEN_PP(self)) != 0) { // this server thinks its name is different than what we have recorded mongo_log(MONGO_LOG_SERVER, MONGO_LOG_INFO TSRMLS_CC, "server: found another name for %s: %s", server->label, Z_STRVAL_PP(self)); // make a new info entry for this name, pointing to our info make_other_le(Z_STRVAL_PP(self), info TSRMLS_CC); } // now we have pinged it at least once info->guts->pinged = 1; zend_hash_find(HASH_P(response), "secondary", strlen("secondary")+1, (void**)&secondary); if (secondary && Z_BVAL_PP(secondary)) { if (!info->guts->readable) { mongo_log(MONGO_LOG_SERVER, MONGO_LOG_INFO TSRMLS_CC, "server: %s is now a secondary", server->label); } info->guts->readable = 1; info->guts->master = 0; } else { if (info->guts->readable) { mongo_log(MONGO_LOG_SERVER, MONGO_LOG_INFO TSRMLS_CC, "server: %s is now not readable", server->label); } info->guts->readable = 0; info->guts->master = 0; } zend_hash_find(HASH_P(response), "maxBsonObjectSize", strlen("maxBsonObjectSize")+1, (void**)&bson); if (bson) { if (Z_TYPE_PP(bson) == IS_LONG) { info->guts->max_bson_size = Z_LVAL_PP(bson); } else if (Z_TYPE_PP(bson) == IS_DOUBLE) { info->guts->max_bson_size = (int)Z_DVAL_PP(bson); } // otherwise, leave as the default else { mongo_log(MONGO_LOG_SERVER, MONGO_LOG_WARNING TSRMLS_CC, "server: could not find max bson size on %s, consider upgrading your server", server->label); } } if (mongo_util_rs__get_ismaster(response TSRMLS_CC)) { if (!info->guts->master) { mongo_log(MONGO_LOG_SERVER, MONGO_LOG_INFO TSRMLS_CC, "server: %s is now primary", server->label); } info->guts->master = 1; info->guts->readable = 1; zval_ptr_dtor(&response); return SUCCESS; } zval_ptr_dtor(&response); return FAILURE; }
RedisArray* ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b_lazy_connect TSRMLS_DC) { int i = 0, host_len, id; char *host, *p; short port; zval **zpData, z_cons, z_ret; RedisSock *redis_sock = NULL; /* function calls on the Redis object */ ZVAL_STRING(&z_cons, "__construct", 0); /* init connections */ for (zend_hash_internal_pointer_reset(hosts); zend_hash_has_more_elements(hosts) == SUCCESS; zend_hash_move_forward(hosts)) { if ((zend_hash_get_current_data(hosts, (void **) &zpData) == FAILURE) || (Z_TYPE_PP(zpData) != IS_STRING)) { efree(ra); return NULL; } ra->hosts[i] = estrdup(Z_STRVAL_PP(zpData)); /* default values */ host = Z_STRVAL_PP(zpData); host_len = Z_STRLEN_PP(zpData); port = 6379; if((p = strrchr(host, ':'))) { /* found port */ host_len = p - host; port = (short)atoi(p+1); } else if(strchr(host,'/') != NULL) { /* unix socket */ port = -1; } /* create Redis object */ MAKE_STD_ZVAL(ra->redis[i]); object_init_ex(ra->redis[i], redis_ce); INIT_PZVAL(ra->redis[i]); call_user_function(&redis_ce->function_table, &ra->redis[i], &z_cons, &z_ret, 0, NULL TSRMLS_CC); /* create socket */ redis_sock = redis_sock_create(host, host_len, port, ra->connect_timeout, ra->pconnect, NULL, retry_interval, b_lazy_connect); if (!b_lazy_connect) { /* connect */ redis_sock_server_open(redis_sock, 1 TSRMLS_CC); } /* attach */ #if PHP_VERSION_ID >= 50400 id = zend_list_insert(redis_sock, le_redis_sock TSRMLS_CC); #else id = zend_list_insert(redis_sock, le_redis_sock); #endif add_property_resource(ra->redis[i], "socket", id); i++; } return ra; }
/** * Applies a format to a message before sending it to the log * * @param string $message * @param int $type * @param int $timestamp * @return string */ PHP_METHOD(Phalcon_Logger_Formatter_Firephp, format) { zval *message, *type, *type_str = NULL, *timestamp; zval *payload, *body, *backtrace, *meta, *encoded; zval *show_backtrace; smart_str result = { NULL, 0, 0 }; int i; Bucket *p; phalcon_fetch_params(0, 3, 0, &message, &type, ×tamp); /** * We intentionally do not use Phalcon's MM for better performance. * All variables allocated with PHALCON_ALLOC_ZVAL() will have * their reference count set to 1 and therefore they can be nicely * put into the result array; when that array will be destroyed, * all inserted variables will be automatically destroyed, too * and we will just save some time by not using Z_ADDREF_P and Z_DELREF_P */ PHALCON_ALLOC_ZVAL(type_str); phalcon_call_method_p1(type_str, this_ptr, "gettypestring", type); phalcon_read_property_this(&show_backtrace, getThis(), SL("_showBacktrace"), PH_NOISY TSRMLS_CC); Z_DELREF_P(show_backtrace); /** * Get the backtrace. This differs for differemt PHP versions. * 5.3.6+ allows us to skip the function arguments which will save some memory * For 5.4+ there is an extra argument. */ PHALCON_ALLOC_ZVAL(backtrace); if (zend_is_true(show_backtrace)) { #if PHP_VERSION_ID < 50306 zend_fetch_debug_backtrace(backtrace, 1, 0 TSRMLS_CC); #elif PHP_VERSION_ID < 50400 zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS TSRMLS_CC); #else zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS, 0 TSRMLS_CC); #endif if (Z_TYPE_P(backtrace) == IS_ARRAY) { HashPosition pos; HashTable *ht = Z_ARRVAL_P(backtrace); zval **ppzval; int found = 0; ulong idx; char *key; uint key_len; /** * At this point we know that the backtrace is the array. * Again, we intentionally do not use Phalcon's API because we know * that we are working with the array / hash table and thus we can * save some time by omitting Z_TYPE_P(x) == IS_ARRAY checks */ for ( zend_hash_internal_pointer_reset_ex(ht, &pos); zend_hash_has_more_elements_ex(ht, &pos) == SUCCESS; ) { zend_hash_get_current_data_ex(ht, (void**)&ppzval, &pos); zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, &pos); zend_hash_move_forward_ex(ht, &pos); if (Z_TYPE_PP(ppzval) == IS_ARRAY) { /** * Here we need to skip the latest calls into Phalcon's core. * Calls to Zend internal functions will have "file" index not set. * We remove these entries from the array. */ if (!found && !zend_hash_exists(Z_ARRVAL_PP(ppzval), SS("file"))) { zend_hash_index_del(ht, idx); } else { /** * Remove args and object indices. They usually give * too much information; this is not suitable to send * in the HTTP headers */ zend_hash_del(Z_ARRVAL_PP(ppzval), "args", sizeof("args")); zend_hash_del(Z_ARRVAL_PP(ppzval), "object", sizeof("object")); found = 1; } } } /** * Now we need to renumber the hash table because we removed several * heading elements. If we don't do this, json_encode() will convert * this array to a JavaScript object which is an unwanted side effect */ p = ht->pListHead; i = 0; while (p != NULL) { p->nKeyLength = 0; p->h = i++; p = p->pListNext; } ht->nNextFreeElement = i; zend_hash_rehash(ht); } } /** * The result will looks like this: * * array( * array('Type' => 'message type', 'Label' => 'message'), * array('backtrace' => array(backtrace goes here) * ) */ MAKE_STD_ZVAL(payload); array_init_size(payload, 2); PHALCON_ALLOC_ZVAL(meta); array_init_size(meta, 4); add_assoc_zval_ex(meta, SS("Type"), type_str); Z_ADDREF_P(message); add_assoc_zval_ex(meta, SS("Label"), message); if (Z_TYPE_P(backtrace) == IS_ARRAY) { zval **ppzval; if (likely(SUCCESS == zend_hash_index_find(Z_ARRVAL_P(backtrace), 0, (void**)&ppzval)) && likely(Z_TYPE_PP(ppzval) == IS_ARRAY)) { zval **file = NULL, **line = NULL; zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")), (void**)&file); zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("line"), zend_inline_hash_func(SS("line")), (void**)&line); if (likely(file != NULL)) { Z_ADDREF_PP(file); add_assoc_zval_ex(meta, SS("File"), *file); } if (likely(line != NULL)) { Z_ADDREF_PP(line); add_assoc_zval_ex(meta, SS("Line"), *line); } } } MAKE_STD_ZVAL(body); array_init_size(body, 1); if (zend_is_true(show_backtrace)) { add_assoc_zval_ex(body, SS("backtrace"), backtrace); } else { zval_ptr_dtor(&backtrace); } add_next_index_zval(payload, meta); add_next_index_zval(payload, body); /** * Convert everything to JSON */ ALLOC_INIT_ZVAL(encoded); phalcon_json_encode(encoded, payload, 0 TSRMLS_CC); /** * As promised, kill the payload and all associated elements */ zval_ptr_dtor(&payload); /** * We don't want to use Phalcon's concatenation API because it * requires the memory manager. Therefore we fall back to using smart strings. * smart_str_alloc4() will allocate all required memory amount (plus some more) * in one go and this allows us to avoid performance penalties due to * memory reallocations. */ smart_str_alloc4(&result, Z_STRLEN_P(encoded) + 2 + 5, 0, i); /** * The format is: * * <size>|[meta,body]| * * Meta and body are contained in encoded inside the array, as required * by the protocol specification * @see http://www.firephp.org/Wiki/Reference/Protocol */ smart_str_append_long(&result, Z_STRLEN_P(encoded)); smart_str_appendc(&result, '|'); smart_str_appendl(&result, Z_STRVAL_P(encoded), Z_STRLEN_P(encoded)); smart_str_appendc(&result, '|'); smart_str_0(&result); /* We don't need the JSON message anymore */ zval_ptr_dtor(&encoded); /* Do not free the samrt string because we steal its data for zval */ RETURN_STRINGL(result.c, result.len, 0); }
/* {{{ php_url_encode_hash */ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, const char *num_prefix, int num_prefix_len, const char *key_prefix, int key_prefix_len, const char *key_suffix, int key_suffix_len, zval *type, char *arg_sep, int enc_type TSRMLS_DC) { char *key = NULL, *ekey, *newprefix, *p; int arg_sep_len, key_len, ekey_len, key_type, newprefix_len; ulong idx; zval **zdata = NULL, *copyzval; if (!ht) { return FAILURE; } if (ht->nApplyCount > 0) { /* 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); for (zend_hash_internal_pointer_reset(ht); (key_type = zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, NULL)) != HASH_KEY_NON_EXISTANT; zend_hash_move_forward(ht) ) { if (key_type == HASH_KEY_IS_STRING && key_len && key[key_len-1] == '\0') { /* We don't want that trailing NULL */ key_len -= 1; } /* handling for private & protected object properties */ if (key && *key == '\0' && type != NULL) { char *tmp; zend_object *zobj = zend_objects_get_address(type TSRMLS_CC); if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) != SUCCESS) { /* private or protected property access outside of the class */ continue; } zend_unmangle_property_name(key, key_len-1, &tmp, &key); key_len = strlen(key); } if (zend_hash_get_current_data_ex(ht, (void **)&zdata, NULL) == FAILURE || !zdata || !(*zdata)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array"); return FAILURE; } if (Z_TYPE_PP(zdata) == IS_ARRAY || Z_TYPE_PP(zdata) == IS_OBJECT) { if (key_type == HASH_KEY_IS_STRING) { if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(key, key_len, &ekey_len); } else { ekey = php_url_encode(key, key_len, &ekey_len); } newprefix_len = key_suffix_len + ekey_len + 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, 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'; } else { /* Is an integer key */ ekey_len = spprintf(&ekey, 0, "%ld", 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'; } ht->nApplyCount++; php_url_encode_hash_ex(HASH_OF(*zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_PP(zdata) == IS_OBJECT ? *zdata : NULL), arg_sep, enc_type TSRMLS_CC); ht->nApplyCount--; efree(newprefix); } else if (Z_TYPE_PP(zdata) == IS_NULL || Z_TYPE_PP(zdata) == IS_RESOURCE) { /* Skip these types */ continue; } else { if (formstr->len) { smart_str_appendl(formstr, arg_sep, arg_sep_len); } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); if (key_type == HASH_KEY_IS_STRING) { if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(key, key_len, &ekey_len); } else { ekey = php_url_encode(key, key_len, &ekey_len); } smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } else { /* Numeric key */ if (num_prefix) { smart_str_appendl(formstr, num_prefix, num_prefix_len); } ekey_len = spprintf(&ekey, 0, "%ld", idx); smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } smart_str_appendl(formstr, key_suffix, key_suffix_len); smart_str_appendl(formstr, "=", 1); switch (Z_TYPE_PP(zdata)) { case IS_STRING: if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len); } else { ekey = php_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len); } break; case IS_LONG: case IS_BOOL: ekey_len = spprintf(&ekey, 0, "%ld", Z_LVAL_PP(zdata)); break; case IS_DOUBLE: ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_PP(zdata)); break; default: /* fall back on convert to string */ MAKE_STD_ZVAL(copyzval); *copyzval = **zdata; zval_copy_ctor(copyzval); convert_to_string_ex(©zval); if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len); } else { ekey = php_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len); } zval_ptr_dtor(©zval); } smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } } return SUCCESS; }
static int php_mongo_command_supports_rp(zval *cmd) { HashPosition pos; char *str; uint str_len; long type; ulong idx; if (!cmd || Z_TYPE_P(cmd) != IS_ARRAY) { return 0; } zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(cmd), &pos); type = zend_hash_get_current_key_ex(Z_ARRVAL_P(cmd), &str, &str_len, &idx, 0, &pos); if (type != HASH_KEY_IS_STRING) { return 0; } /* Commands in MongoDB are case-sensitive */ if (str_len == 6) { if (strcmp(str, "count") == 0 || strcmp(str, "group") == 0) { return 1; } return 0; } if (str_len == 8) { if (strcmp(str, "dbStats") == 0 || strcmp(str, "geoNear") == 0 || strcmp(str, "geoWalk") == 0) { return 1; } return 0; } if (str_len == 9) { if (strcmp(str, "distinct") == 0) { return 1; } return 0; } if (str_len == 10) { if (strcmp(str, "aggregate") == 0 || strcmp(str, "collStats") == 0 || strcmp(str, "geoSearch") == 0) { return 1; } if (strcmp(str, "mapreduce") == 0 || strcmp(str, "mapReduce") == 0) { zval **value = NULL; if (zend_hash_find(Z_ARRVAL_P(cmd), "out", 4, (void **)&value) == SUCCESS) { if (Z_TYPE_PP(value) == IS_ARRAY) { if (zend_hash_exists(Z_ARRVAL_PP(value), "inline", 7)) { return 1; } } } } return 0; } if (str_len == 23) { if (strcmp(str, "parallelCollectionScan") == 0) { return 1; } return 0; } return 0; }
// PHP函数参数转换为go类型的参数 static void* phpgo_function_conv_arg(int cbid, int idx, char ch, int zty, zval **zarg) { int prmty = zty; void *rv = NULL; if (ch == 's') { if (prmty != IS_STRING) { zend_error(E_WARNING, "Parameters type not match, need (%c), given: %s", ch, type2name(prmty)); } convert_to_string_ex(zarg); char *arg = Z_STRVAL_PP(zarg); printf("arg%d(%c), %s(%d)\n", idx, ch, arg, Z_STRLEN_PP(zarg)); goapi_new_value(GT_String, (uint64_t)arg, &rv); } else if (ch == 'l') { if (prmty != IS_LONG) { zend_error(E_WARNING, "Parameters type not match, need (%c), given: %s", ch, type2name(prmty)); } convert_to_long_ex(zarg); long arg = (long)Z_LVAL_PP(zarg); printf("arg%d(%c), %d\n", idx, ch, arg); goapi_new_value(GT_Int64, (uint64_t)arg, &rv); } else if (ch == 'b') { convert_to_boolean_ex(zarg); zend_bool arg = (zend_bool)Z_BVAL_PP(zarg); goapi_new_value(GT_Bool, (uint64_t)arg, &rv); } else if (ch == 'd') { convert_to_double_ex(zarg); double arg = (double)Z_DVAL_PP(zarg); double* parg = calloc(1, sizeof(double)); *parg = (double)Z_DVAL_PP(zarg); // argv[idx] = (void*)(ulong)arg; // error // memcpy(&argv[idx], &arg, sizeof(argv[idx])); // ok // float32(uintptr(ax)) goapi_new_value(GT_Float64, (uint64_t)parg, &rv); } else if (ch == 'a') { if (Z_TYPE_PP(zarg) == IS_STRING) { char *arg = Z_STRVAL_PP(zarg); goapi_new_value(GT_String, (uint64_t)arg, &rv); #ifdef ZEND_ENGINE_3 } else if (Z_TYPE_PP(zarg) == _IS_BOOL) { #else } else if (Z_TYPE_PP(zarg) == IS_BOOL) { #endif zend_bool arg = (zend_bool)Z_BVAL_PP(zarg); goapi_new_value(GT_Bool, (uint64_t)arg, &rv); } else if (Z_TYPE_PP(zarg) == IS_DOUBLE) { double* parg = calloc(1, sizeof(double)); *parg = (double)Z_DVAL_PP(zarg); goapi_new_value(GT_Float64, (uint64_t)parg, &rv); } else if (Z_TYPE_PP(zarg) == IS_LONG) { long arg = (long)Z_LVAL_PP(zarg); goapi_new_value(GT_Int64, (uint64_t)arg, &rv); } else if (Z_TYPE_PP(zarg) == IS_OBJECT) { void *parg = (void*)zarg; goapi_new_value(GT_UnsafePointer, (uint64_t)parg, &rv); } else if (Z_TYPE_PP(zarg) == IS_RESOURCE) { void *parg = (void*)zarg; goapi_new_value(GT_UnsafePointer, (uint64_t)parg, &rv); } else { printf("arg%d(%c), %s(%d) unsported to Any\n", idx, ch, type2name(Z_TYPE_PP(zarg)), Z_TYPE_PP(zarg)); } // TODO array/vector convert } else if (ch == 'v') { HashTable *arr_hash = Z_ARRVAL_PP(zarg); HashPosition pos; zval **edata; for (zend_hash_internal_pointer_reset_ex(arr_hash, &pos); #ifdef ZEND_ENGINE_3 (edata = zend_hash_get_current_data_ex(arr_hash, &pos)) != NULL; #else zend_hash_get_current_data_ex(arr_hash, (void**)&edata, &pos) == SUCCESS; #endif zend_hash_move_forward_ex(arr_hash, &pos)) { if (rv == NULL) { switch (Z_TYPE_PP(edata)) { case IS_LONG: goapi_array_new(GT_Int64, &rv); break; default: goapi_array_new(GT_String, &rv); break; } } switch (Z_TYPE_PP(edata)) { case IS_LONG: goapi_array_push(rv, (void*)Z_LVAL_PP(edata), &rv); break; default: convert_to_string_ex(edata); printf("array idx(%d)=T(%d=%s, val=%s)\n", pos, Z_TYPE_PP(edata), type2name(Z_TYPE_PP(edata)), Z_STRVAL_PP(edata)); goapi_array_push(rv, Z_STRVAL_PP(edata), &rv); break; } } // TODO array/map convert } else if (ch == 'm') {
int php_tmpl_parse(zval** dest, t_template* tmpl, zval* path, HashPosition* pos, zval** data) { uint tag_num; int i; zval **ztag; t_tmpl_tag *tag, *ctx; char *buf; ulong buf_alloc; zval *new_path; zval **tag_data; HashPosition cur_pos, saved_pos, dup_tag_pos; uint offset; unsigned short need_skip; zval **iteration; char *key_tag_key; uint key_tag_len; ulong key_tag_index; /* Initialize variables */ buf_alloc = TMPL_MAX_TAG_LEN; buf = (char*)emalloc(buf_alloc); MAKE_STD_ZVAL(new_path); ZVAL_STRINGL(new_path, buf, 0, 0); dup_tag_pos = NULL; /* Get the context's info from tags array */ if(!pos) { /* This is not a recursion call. Look for the context's last non-empty iteration */ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(tmpl->tags), &cur_pos); i = 0; /* we'll set this flag when found the context */ do { if(HASH_KEY_IS_STRING != zend_hash_get_current_key_ex(Z_ARRVAL_P(tmpl->tags), &key_tag_key, &key_tag_len, &key_tag_index, 0, &cur_pos)) break; if(SUCCESS != zend_hash_get_current_data_ex(Z_ARRVAL_P(tmpl->tags), (void**)&ztag, &cur_pos)) break; tag = ctx = (t_tmpl_tag*)Z_STRVAL_PP(ztag); if(TMPL_CONTEXT != ctx->typ) continue; /* get out of the loop if we're inside of the context we need */ if((uint)ZL(path) == key_tag_len-1 && !memcmp(ZV(path), key_tag_key, ZL(path))) { i = 1; break; } } while(SUCCESS == zend_hash_move_forward_ex(Z_ARRVAL_P(tmpl->tags), &cur_pos)); if(!i) { TMPL_PARSE_CLEANUP; return FAILURE; } tag_data = php_tmpl_get_iteration(tmpl, path, TMPL_ITERATION_PARENT); } else { cur_pos = *pos; tag = ctx = (t_tmpl_tag*)Z_STRVAL_PP((zval**)(cur_pos->pData)); tag_data = data; } saved_pos = cur_pos; /* Check all iterations in the opened context */ zend_hash_internal_pointer_reset(Z_ARRVAL_PP(tag_data)); do { if(FAILURE == zend_hash_get_current_data(Z_ARRVAL_PP(tag_data), (void*)&iteration)) break; /* Uncomment the following line to avoid parsing of empty iterations */ /* if(pos && !zend_hash_num_elements(Z_ARRVAL_PP(iteration))) break; */ /* Initialize the offset from the template's content begining */ offset = (1 == ZL(ctx->name) && '/' == ZV(ctx->name)[0]) ? 0 : ctx->loff + ZL(tmpl->ctx_ol) + ZL(ctx->name) + ZL(tmpl->ctx_or); /* We only need tags which are inside of the context */ cur_pos = saved_pos; for(tag_num = 0; tag_num < ctx->tag_num; tag_num++) { if(FAILURE == zend_hash_move_forward_ex(Z_ARRVAL_P(tmpl->tags), &cur_pos)) break; if(FAILURE == zend_hash_get_current_data_ex(Z_ARRVAL_P(tmpl->tags), (void**)&ztag, &cur_pos)) break; tag = (t_tmpl_tag*)Z_STRVAL_PP(ztag); if(NULL == dup_tag_pos && zend_hash_num_elements(Z_ARRVAL_P(tmpl->dup_tag))) { zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(tmpl->dup_tag), &dup_tag_pos); do { if(FAILURE == zend_hash_get_current_data_ex(Z_ARRVAL_P(tmpl->dup_tag), (void**)&ztag, &dup_tag_pos)) break; } while(Z_TMPL_TAG(ztag)->loff < offset && SUCCESS == zend_hash_move_forward_ex(Z_ARRVAL_P(tmpl->dup_tag), &dup_tag_pos)); } php_tmpl_parse_check_memory(tmpl, &dup_tag_pos, tag, TMPL_TAG, iteration, dest, &offset); TMPL_PARSE_DEST_ADD(offset, tag->loff - offset); offset = tag->roff; need_skip = (FAILURE == zend_hash_find(Z_ARRVAL_PP(iteration), ZV(tag->name), ZL(tag->name)+1, (void*)&ztag)); if(!need_skip) { if(TMPL_CONTEXT == tag->typ && IS_ARRAY == Z_TYPE_PP(ztag)) { /* Processing a context */ /* Make a recursive call */ if(buf_alloc <= (unsigned)(ZL(path)+1+ZL(tag->name)+1)) { while(buf_alloc <= (unsigned)(ZL(path)+1+ZL(tag->name)+1)) buf_alloc <<= 1; (char*)ZV(new_path) = erealloc(ZV(new_path), buf_alloc); } sprintf(ZV(new_path), (1 == ZL(path) && '/' == ZV(path)[0]) ? "%s%s" : "%s/%s", ZV(path), ZV(tag->name)); ZL(new_path) = ZL(path) + ZL(tag->name) + ((1 == ZL(path) && '/' == ZV(path)[0]) ? 0 : 1); php_tmpl_parse(dest, tmpl, new_path, &cur_pos, ztag); } else { /* Processing a tag */ TMPL_PARSE_DEST_ADD(Z_STRVAL_PP(ztag)-Z_STRVAL_P(tmpl->original), Z_STRLEN_PP(ztag)); if(TMPL_CONTEXT == tag->typ) need_skip = 1; } } if(need_skip && TMPL_CONTEXT == tag->typ) { for(i=0; i < (int)tag->tag_num; i++) { if(FAILURE == zend_hash_move_forward_ex(Z_ARRVAL_P(tmpl->tags), &cur_pos)) break; if(FAILURE == zend_hash_get_current_data_ex(Z_ARRVAL_P(tmpl->tags), (void**)&ztag, &cur_pos)) break; i -= (TMPL_CONTEXT == Z_TMPL_TAG(ztag)->typ) ? Z_TMPL_TAG(ztag)->tag_num : 0; } } } php_tmpl_parse_check_memory(tmpl, &dup_tag_pos, ctx, TMPL_CONTEXT, iteration, dest, &offset); if(1 != ZL(path) || '/' != ZV(path)[0]) { TMPL_PARSE_DEST_ADD(offset, ctx->roff - offset - ZL(tmpl->ctx_cl) - ZL(ctx->name)*(ZL(tmpl->ctx_cr)?1:0) - ZL(tmpl->ctx_cr)); } else { TMPL_PARSE_DEST_ADD(offset, ZL(tmpl->original)-offset); } } while(SUCCESS == zend_hash_move_forward(Z_ARRVAL_PP(tag_data))); if(pos) *pos = cur_pos; TMPL_PARSE_CLEANUP; return SUCCESS; }
PHP_COUCHBASE_LOCAL void php_couchbase_get_delayed_impl(INTERNAL_FUNCTION_PARAMETERS, int oo) /* {{{ */ { zval *res, *akeys; long with_cas = 0; lcb_time_t exp = {0}; long expiry = 0; zend_bool lock = 0; int argflags = PHP_COUCHBASE_ARG_F_ASYNC; php_couchbase_res *couchbase_res; #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2 zend_fcall_info fci = {0}; zend_fcall_info_cache fci_cache = {0}; if (oo) { argflags |= PHP_COUCHBASE_ARG_F_OO; } else { argflags |= PHP_COUCHBASE_ARG_F_FUNCTIONAL; } PHP_COUCHBASE_GET_PARAMS_WITH_ZV(res, couchbase_res, argflags, "a|lf!lb", &akeys, &with_cas, &fci, &fci_cache, &expiry, &lock); #else if (oo) { argflags |= PHP_COUCHBASE_ARG_F_OO; } else { argflags |= PHP_COUCHBASE_ARG_F_FUNCTIONAL; } zval *callback = NULL; PHP_COUCHBASE_GET_PARAMS_WITH_ZV(res, couchbase_res, argflags, "a|lzlb", &akeys, &with_cas, &callback, &expiry, &lock); if (callback && Z_TYPE_P(callback) != IS_NULL && !zend_is_callable(callback, 0, NULL)) { couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo, cb_exception, "third argument is expected to be a valid callback"); return; } #endif { zval **ppzval; lcb_error_t retval; php_couchbase_ctx *ctx; char **keys; long nkey, *klens, i; nkey = zend_hash_num_elements(Z_ARRVAL_P(akeys)); keys = ecalloc(nkey, sizeof(char *)); klens = ecalloc(nkey, sizeof(long)); for (i = 0, zend_hash_internal_pointer_reset(Z_ARRVAL_P(akeys)); zend_hash_has_more_elements(Z_ARRVAL_P(akeys)) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(akeys)), i++) { if (zend_hash_get_current_data(Z_ARRVAL_P(akeys), (void **)&ppzval) == FAILURE) { nkey--; continue; } if (IS_ARRAY != Z_TYPE_PP(ppzval)) { convert_to_string_ex(ppzval); } if (!Z_STRLEN_PP(ppzval)) { nkey--; continue; } if (couchbase_res->prefix_key_len) { klens[i] = spprintf(&(keys[i]), 0, "%s_%s", couchbase_res->prefix_key, Z_STRVAL_PP(ppzval)); } else { keys[i] = Z_STRVAL_PP(ppzval); klens[i] = Z_STRLEN_PP(ppzval); } } if (!nkey) { efree(keys); efree(klens); return; } couchbase_res->seqno += nkey; ctx = ecalloc(1, sizeof(php_couchbase_ctx)); ctx->res = couchbase_res; ctx->flags = with_cas; { lcb_get_cmd_t **commands = ecalloc(nkey, sizeof(lcb_get_cmd_t *)); int ii; if (expiry) { exp = pcbc_check_expiry(expiry); } for (ii = 0; ii < nkey; ++ii) { lcb_get_cmd_t *cmd = ecalloc(1, sizeof(lcb_get_cmd_t)); commands[ii] = cmd; cmd->v.v0.key = keys[ii]; cmd->v.v0.nkey = klens[ii]; cmd->v.v0.lock = (int)lock; cmd->v.v0.exptime = exp; /* NB: this assumes that sizeof(lcb_time_t) == sizeof(long) */ } retval = lcb_get(couchbase_res->handle, ctx, nkey, (const lcb_get_cmd_t * const *)commands); for (ii = 0; ii < nkey; ++ii) { efree(commands[ii]); } efree(commands); } if (LCB_SUCCESS != retval) { if (couchbase_res->prefix_key_len) { int i; for (i = 0; i < nkey; i++) { efree(keys[i]); } } efree(keys); efree(klens); efree(ctx); couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo, cb_lcb_exception, "Failed to schedule delayed get request: %s", lcb_strerror(couchbase_res->handle, retval)); return; } couchbase_res->async = 1; couchbase_res->async_ctx = ctx; if (couchbase_res->prefix_key_len) { int i; for (i = 0; i < nkey; i++) { efree(keys[i]); } } efree(keys); efree(klens); if ( #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2 fci.size #else callback #endif ) { zval *result, **ppzval, *retval_ptr = NULL; zval **params[2]; MAKE_STD_ZVAL(result); array_init(result); ctx->rv = result; pcbc_start_loop(couchbase_res); couchbase_res->async = 0; for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(result)); zend_hash_has_more_elements(Z_ARRVAL_P(result)) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(result))) { if (zend_hash_get_current_data(Z_ARRVAL_P(result), (void **)&ppzval) == FAILURE) { continue; } params[0] = &res; params[1] = ppzval; #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 2 fci.retval_ptr_ptr = &retval_ptr; fci.param_count = 2; fci.params = params; zend_call_function(&fci, &fci_cache TSRMLS_CC); #else call_user_function_ex(EG(function_table), NULL, callback, &retval_ptr, 2, params, 0, NULL TSRMLS_CC); #endif if (retval_ptr != NULL) { zval_ptr_dtor(&retval_ptr); } } zval_ptr_dtor(&result); efree(ctx); } } RETURN_TRUE; }
zval * activerecord_create_conditions_from_underscored_string( char * str, int str_len, zval * values, zval * map ) { int i, valcount, strsize, curstrsize; char * conditions; zend_bool use_map, unfinished = 1; zval * retval, * condsval; if( !name_len || Z_TYPE_P(values) != IS_ARRAY ) return NULL; MAKE_STD_ZVAL( retval ); array_init( retval ); add_index_string( retval, 0, "", 1); use_map = ( map != NULL && Z_TYPE_P(map) == IS_ARRAY ); valcount = zend_hash_num_elements(Z_ARRVAL_P(values)); conditions = (char*)emalloc( strsize = valcount*20 ); for( i = 0; strstr( str, "_and_" ) || strstr( str, "_or_" ) || unfinished; i++ ) { char *attribute, *tmp; zend_bool and_condition; zval **alias; if( tmp = strstr(str,"_and_") ) and_condition = 1; else { tmp = strstr(str,"_or_"); and_condition = 0; } if( tmp ) { attribute = (char*)emalloc( tmp - str ); strncpy( attribute, str, tmp - str ); str = tmp + (and_condition? 5 : 4); } else { unfinished = 0; attribute = str; } if( i > 0 ) { if( use_map && zend_hash_find( Z_ARRVAL_P(map), attribute, sizeof(attribute), (void**)&alias ) == SUCCESS ) attribute = Z_STRVAL_PP(alias); if( curstrsize + 14 + strlen(attribute) > strsize ) { tmp = (char*)emalloc( strsize*2 ); strncpy( tmp, conditions, curstrsize ); efree( conditions ); conditions = tmp; strsize *= 2; } strsize += (and_condition? 5 : 4) + strlen(attribute); strcat( conditions, and_condition? " AND " : " OR " ); strcat( conditions, activerecord_sql_quote_name(attribute) ); if( i < valcount ) { zval **value; zend_hash_index_find( Z_ARRVAL_P(values), i, (void**)&value ); if( Z_TYPE_PP(value) != IS_NULL ) { strcat( conditions, Z_TYPE_PP(value) == IS_ARRAY? " IN(?)" : "=?"; curstrsize += Z_TYPE_PP(value) == IS_ARRAY? 6 : 2; add_next_index_zval( retval, *value ); } else { strcat( conditions, " IS NULL " ); curstrsize += 9; } }
U_CFUNC PHP_FUNCTION(intlcal_set) { long arg1, arg2, arg3, arg4, arg5, arg6; zval **args_a[7] = {0}, ***args = &args_a[0]; int i; int variant; /* number of args of the set() overload */ CALENDAR_METHOD_INIT_VARS; /* must come before zpp because zpp would convert the args in the stack to 0 */ if (ZEND_NUM_ARGS() > (getThis() ? 6 : 7) || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_set: too many arguments", 0 TSRMLS_CC); RETURN_FALSE; } if (!getThis()) { args++; } variant = ZEND_NUM_ARGS() - (getThis() ? 0 : 1); while (variant > 2 && Z_TYPE_PP(args[variant - 1]) == IS_NULL) { variant--; } if (variant == 4 || zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|llll", &object, Calendar_ce_ptr, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_set: bad arguments", 0 TSRMLS_CC); RETURN_FALSE; } for (i = 0; i < variant; i++) { if (Z_LVAL_PP(args[i]) < INT32_MIN || Z_LVAL_PP(args[i]) > INT32_MAX) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_set: at least one of the arguments has an absolute " "value that is too large", 0 TSRMLS_CC); RETURN_FALSE; } } if (variant == 2 && (arg1 < 0 || arg1 >= UCAL_FIELD_COUNT)) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_set: invalid field", 0 TSRMLS_CC); RETURN_FALSE; } CALENDAR_METHOD_FETCH_OBJECT; if (variant == 2) { co->ucal->set((UCalendarDateFields)arg1, (int32_t)arg2); } else if (variant == 3) { co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3); } else if (variant == 5) { co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5); } else if (variant == 6) { co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5, (int32_t)arg6); } RETURN_TRUE; }
static void php_mongo_enumerate_collections(INTERNAL_FUNCTION_PARAMETERS, int full_collection) { zend_bool system_col = 0; zval *nss, *collection, *cursor, *list, *next; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &system_col) == FAILURE) { return; } /* select db.system.namespaces collection */ MAKE_STD_ZVAL(nss); ZVAL_STRING(nss, "system.namespaces", 1); MAKE_STD_ZVAL(collection); MONGO_METHOD1(MongoDB, selectCollection, collection, getThis(), nss); /* list to return */ MAKE_STD_ZVAL(list); array_init(list); /* do find */ MAKE_STD_ZVAL(cursor); MONGO_METHOD(MongoCollection, find, cursor, collection); /* populate list */ MAKE_STD_ZVAL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); while (!IS_SCALAR_P(next)) { zval *c, *zname; zval **collection; char *name, *first_dot, *system; /* check that the ns is valid and not an index (contains $) */ if ( zend_hash_find(HASH_P(next), "name", 5, (void**)&collection) == FAILURE || ( Z_TYPE_PP(collection) == IS_STRING && strchr(Z_STRVAL_PP(collection), '$') ) ) { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } /* check that this isn't a system ns */ first_dot = strchr(Z_STRVAL_PP(collection), '.'); system = strstr(Z_STRVAL_PP(collection), ".system."); if ( (!system_col && (system && first_dot == system)) || (name = strchr(Z_STRVAL_PP(collection), '.')) == 0) { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } /* take a substring after the first "." */ name++; /* "foo." was allowed in earlier versions */ if (*name == '\0') { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } if (full_collection) { MAKE_STD_ZVAL(c); ZVAL_NULL(c); MAKE_STD_ZVAL(zname); ZVAL_NULL(zname); /* name must be copied because it is a substring of a string that * will be garbage collected in a sec */ ZVAL_STRING(zname, name, 1); MONGO_METHOD1(MongoDB, selectCollection, c, getThis(), zname); add_next_index_zval(list, c); zval_ptr_dtor(&zname); } else { add_next_index_string(list, name, 1); } zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); } zval_ptr_dtor(&next); zval_ptr_dtor(&nss); zval_ptr_dtor(&cursor); zval_ptr_dtor(&collection); RETURN_ZVAL(list, 0, 1); }
static void pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAMETERS, int timedwait) /* {{{ */ { zval *user_set, **user_signo, *user_siginfo = NULL; long tv_sec = 0, tv_nsec = 0; sigset_t set; HashPosition pos; int signo; siginfo_t siginfo; struct timespec timeout; if (timedwait) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zll", &user_set, &user_siginfo, &tv_sec, &tv_nsec) == FAILURE) { return; } } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &user_set, &user_siginfo) == FAILURE) { return; } } if (sigemptyset(&set) != 0) { PCNTL_G(last_error) = errno; php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(user_set), &pos); while (zend_hash_get_current_data_ex(Z_ARRVAL_P(user_set), (void **)&user_signo, &pos) == SUCCESS) { if (Z_TYPE_PP(user_signo) != IS_LONG) { SEPARATE_ZVAL(user_signo); convert_to_long_ex(user_signo); } signo = Z_LVAL_PP(user_signo); if (sigaddset(&set, signo) != 0) { PCNTL_G(last_error) = errno; php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } zend_hash_move_forward_ex(Z_ARRVAL_P(user_set), &pos); } if (timedwait) { timeout.tv_sec = (time_t) tv_sec; timeout.tv_nsec = tv_nsec; signo = sigtimedwait(&set, &siginfo, &timeout); } else { signo = sigwaitinfo(&set, &siginfo); } if (signo == -1 && errno != EAGAIN) { PCNTL_G(last_error) = errno; php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); } /* * sigtimedwait and sigwaitinfo can return 0 on success on some * platforms, e.g. NetBSD */ if (!signo && siginfo.si_signo) { signo = siginfo.si_signo; } if (signo > 0 && user_siginfo) { if (Z_TYPE_P(user_siginfo) != IS_ARRAY) { zval_dtor(user_siginfo); array_init(user_siginfo); } else { zend_hash_clean(Z_ARRVAL_P(user_siginfo)); } add_assoc_long_ex(user_siginfo, "signo", sizeof("signo"), siginfo.si_signo); add_assoc_long_ex(user_siginfo, "errno", sizeof("errno"), siginfo.si_errno); add_assoc_long_ex(user_siginfo, "code", sizeof("code"), siginfo.si_code); switch(signo) { #ifdef SIGCHLD case SIGCHLD: add_assoc_long_ex(user_siginfo, "status", sizeof("status"), siginfo.si_status); # ifdef si_utime add_assoc_double_ex(user_siginfo, "utime", sizeof("utime"), siginfo.si_utime); # endif # ifdef si_stime add_assoc_double_ex(user_siginfo, "stime", sizeof("stime"), siginfo.si_stime); # endif add_assoc_long_ex(user_siginfo, "pid", sizeof("pid"), siginfo.si_pid); add_assoc_long_ex(user_siginfo, "uid", sizeof("uid"), siginfo.si_uid); break; #endif case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: add_assoc_double_ex(user_siginfo, "addr", sizeof("addr"), (long)siginfo.si_addr); break; #ifdef SIGPOLL case SIGPOLL: add_assoc_long_ex(user_siginfo, "band", sizeof("band"), siginfo.si_band); # ifdef si_fd add_assoc_long_ex(user_siginfo, "fd", sizeof("fd"), siginfo.si_fd); # endif break; #endif EMPTY_SWITCH_DEFAULT_CASE(); } } RETURN_LONG(signo); }
static zval * php_yar_client_parse_response(char *ret, size_t len, int throw_exception TSRMLS_DC) /* {{{ */ { zval *retval, *response; yar_header_t *header; char *err_msg; MAKE_STD_ZVAL(retval); ZVAL_FALSE(retval); if (!(header = php_yar_protocol_parse(&ret, &len, &err_msg TSRMLS_CC))) { php_yar_client_trigger_error(throw_exception TSRMLS_CC, YAR_ERR_PROTOCOL, "%s", err_msg); if (YAR_G(debug)) { php_yar_debug_client("0: malformed response '%s'", ret); } efree(err_msg); return retval; } if (!len || !header->body_len) { php_yar_client_trigger_error(throw_exception TSRMLS_CC, 0, "server responsed empty body"); return retval; } if (YAR_G(debug)) { php_yar_debug_client("%ld: server responsed: packager '%s', len '%ld', content '%s'", header->id, ret, len - 8, ret + 8); } if (!(response = php_yar_packager_unpack(ret, len, &err_msg TSRMLS_CC))) { php_yar_client_trigger_error(throw_exception TSRMLS_CC, YAR_ERR_PACKAGER, "%s", err_msg); efree(err_msg); return retval; } if (response && IS_ARRAY == Z_TYPE_P(response)) { zval **ppzval; uint status; HashTable *ht = Z_ARRVAL_P(response); if (zend_hash_find(ht, ZEND_STRS("s"), (void **)&ppzval) == FAILURE) { } convert_to_long(*ppzval); status = Z_LVAL_PP(ppzval); if (status == YAR_ERR_OKEY) { if (zend_hash_find(ht, ZEND_STRS("o"), (void **)&ppzval) == SUCCESS) { PHPWRITE(Z_STRVAL_PP(ppzval), Z_STRLEN_PP(ppzval)); } } else if (status == YAR_ERR_EXCEPTION) { if (zend_hash_find(ht, ZEND_STRS("e"), (void **)&ppzval) == SUCCESS) { if (throw_exception) { zval *ex, **property; MAKE_STD_ZVAL(ex); object_init_ex(ex, yar_server_exception_ce); if (zend_hash_find(Z_ARRVAL_PP(ppzval), ZEND_STRS("message"), (void **)&property) == SUCCESS) { zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("message"), *property TSRMLS_CC); } if (zend_hash_find(Z_ARRVAL_PP(ppzval), ZEND_STRS("code"), (void **)&property) == SUCCESS) { zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("code"), *property TSRMLS_CC); } if (zend_hash_find(Z_ARRVAL_PP(ppzval), ZEND_STRS("file"), (void **)&property) == SUCCESS) { zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("file"), *property TSRMLS_CC); } if (zend_hash_find(Z_ARRVAL_PP(ppzval), ZEND_STRS("line"), (void **)&property) == SUCCESS) { zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("line"), *property TSRMLS_CC); } if (zend_hash_find(Z_ARRVAL_PP(ppzval), ZEND_STRS("_type"), (void **)&property) == SUCCESS) { zend_update_property(yar_server_exception_ce, ex, ZEND_STRL("_type"), *property TSRMLS_CC); } zend_throw_exception_object(ex TSRMLS_CC); } else { zval **msg, **code; if (zend_hash_find(Z_ARRVAL_PP(ppzval), ZEND_STRS("message"), (void **)&msg) == SUCCESS && zend_hash_find(Z_ARRVAL_PP(ppzval), ZEND_STRS("code"), (void **)&code) == SUCCESS) { convert_to_string_ex(msg); convert_to_long_ex(code); php_yar_client_trigger_error(0 TSRMLS_CC, Z_LVAL_PP(code), "server threw an exception with message `%s`", Z_STRVAL_PP(msg)); } } } } else if (zend_hash_find(ht, ZEND_STRS("e"), (void **)&ppzval) == SUCCESS && IS_STRING == Z_TYPE_PP(ppzval)) { php_yar_client_trigger_error(throw_exception TSRMLS_CC, status, "%s", Z_STRVAL_PP(ppzval)); } if (zend_hash_find(ht, ZEND_STRS("r"), (void **)&ppzval) == SUCCESS) { ZVAL_ZVAL(retval, *ppzval, 1, 0); } zval_ptr_dtor(&response); } else if (response) { zval_ptr_dtor(&response); } return retval; } /* }}} */
/* {{{ _php_image_output_ctx */ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) { zval **imgind, **file, **quality, **basefilter; gdImagePtr im; char *fn = NULL; FILE *fp = NULL; int argc = ZEND_NUM_ARGS(); int q = -1, i; int f = -1; gdIOCtx *ctx; /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp(). * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called * from imagey<type>(). */ if (argc < 2 && image_type == PHP_GDIMG_TYPE_XBM) { WRONG_PARAM_COUNT; } if (argc < 1 || argc > 4 || zend_get_parameters_ex(argc, &imgind, &file, &quality, &basefilter) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(im, gdImagePtr, imgind, -1, "Image", phpi_get_le_gd()); if (argc > 1) { if (argc >= 2 && Z_TYPE_PP(file) != IS_NULL) { convert_to_string_ex(file); } fn = Z_STRVAL_PP(file); if (argc >= 3) { convert_to_long_ex(quality); q = Z_LVAL_PP(quality);/* or colorindex for foreground of BW images (defaults to black) */ if (argc == 4) { convert_to_long_ex(basefilter); f = Z_LVAL_PP(basefilter); } } } if (argc > 1 && (Z_TYPE_PP(file) != IS_NULL && ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))))) { PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename"); fp = VCWD_FOPEN(fn, "wb"); if (!fp) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", fn, strerror(errno)); RETURN_FALSE; } ctx = gdNewFileCtx(fp); } else { ctx = emalloc(sizeof(gdIOCtx)); ctx->putC = _php_image_output_putc; ctx->putBuf = _php_image_output_putbuf; #if HAVE_LIBGD204 ctx->gd_free = _php_image_output_ctxfree; #else ctx->free = _php_image_output_ctxfree; #endif #if APACHE && defined(CHARSET_EBCDIC) /* XXX this is unlikely to work any more [email protected] */ /* This is a binary file already: avoid EBCDIC->ASCII conversion */ ap_bsetflag(php3_rqst->connection->client, B_EBCDIC2ASCII, 0); #endif } switch(image_type) { case PHP_GDIMG_CONVERT_WBM: if(q<0||q>255) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q); } case PHP_GDIMG_TYPE_JPG: (*func_p)(im, ctx, q); break; case PHP_GDIMG_TYPE_PNG: (*func_p)(im, ctx, q, f); break; case PHP_GDIMG_TYPE_XBM: case PHP_GDIMG_TYPE_WBM: if (argc < 3) { for(i=0; i < gdImageColorsTotal(im); i++) { if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break; } q = i; } if (image_type == PHP_GDIMG_TYPE_XBM) { (*func_p)(im, fn, q, ctx); } else { (*func_p)(im, q, ctx); } break; default: (*func_p)(im, ctx); break; } #if HAVE_LIBGD204 ctx->gd_free(ctx); #else ctx->free(ctx); #endif if(fp) { fflush(fp); fclose(fp); } RETURN_TRUE; }
void zephir_concat_vvvs(zval **result, zval *op1, zval *op2, zval *op3, const char *op4, zend_uint op4_len, int self_var TSRMLS_DC) { zval result_copy, op1_copy, op2_copy, op3_copy; int use_copy = 0, use_copy1 = 0, use_copy2 = 0, use_copy3 = 0; uint offset = 0, length; if (Z_TYPE_P(op1) != IS_STRING) { zend_make_printable_zval(op1, &op1_copy, &use_copy1); if (use_copy1) { op1 = &op1_copy; } } if (Z_TYPE_P(op2) != IS_STRING) { zend_make_printable_zval(op2, &op2_copy, &use_copy2); if (use_copy2) { op2 = &op2_copy; } } if (Z_TYPE_P(op3) != IS_STRING) { zend_make_printable_zval(op3, &op3_copy, &use_copy3); if (use_copy3) { op3 = &op3_copy; } } length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2) + Z_STRLEN_P(op3) + op4_len; if (self_var) { if (Z_TYPE_PP(result) != IS_STRING) { zend_make_printable_zval(*result, &result_copy, &use_copy); if (use_copy) { ZEPHIR_CPY_WRT_CTOR(*result, (&result_copy)); } } offset = Z_STRLEN_PP(result); length += offset; Z_STRVAL_PP(result) = (char *) str_erealloc(Z_STRVAL_PP(result), length + 1); } else { Z_STRVAL_PP(result) = (char *) emalloc(length + 1); } memcpy(Z_STRVAL_PP(result) + offset, Z_STRVAL_P(op1), Z_STRLEN_P(op1)); memcpy(Z_STRVAL_PP(result) + offset + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); memcpy(Z_STRVAL_PP(result) + offset + Z_STRLEN_P(op1) + Z_STRLEN_P(op2), Z_STRVAL_P(op3), Z_STRLEN_P(op3)); memcpy(Z_STRVAL_PP(result) + offset + Z_STRLEN_P(op1) + Z_STRLEN_P(op2) + Z_STRLEN_P(op3), op4, op4_len); Z_STRVAL_PP(result)[length] = 0; Z_TYPE_PP(result) = IS_STRING; Z_STRLEN_PP(result) = length; if (use_copy1) { zval_dtor(op1); } if (use_copy2) { zval_dtor(op2); } if (use_copy3) { zval_dtor(op3); } if (use_copy) { zval_dtor(&result_copy); } }
int msgpack_unserialize_map_item( msgpack_unserialize_data *unpack, zval **container, zval *key, zval *val) { long deps; TSRMLS_FETCH(); if (MSGPACK_G(php_only)) { zend_class_entry *ce; if (Z_TYPE_P(key) == IS_NULL) { unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; if (Z_TYPE_P(val) == IS_LONG) { switch (Z_LVAL_P(val)) { case MSGPACK_SERIALIZE_TYPE_REFERENCE: Z_SET_ISREF_PP(container); break; case MSGPACK_SERIALIZE_TYPE_RECURSIVE: unpack->type = MSGPACK_SERIALIZE_TYPE_RECURSIVE; break; case MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT: unpack->type = MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT; break; case MSGPACK_SERIALIZE_TYPE_OBJECT_REFERENCE: unpack->type = MSGPACK_SERIALIZE_TYPE_OBJECT_REFERENCE; break; case MSGPACK_SERIALIZE_TYPE_OBJECT: unpack->type = MSGPACK_SERIALIZE_TYPE_OBJECT; break; default: break; } } else if (Z_TYPE_P(val) == IS_STRING) { ce = msgpack_unserialize_class( container, Z_STRVAL_P(val), Z_STRLEN_P(val)); if (ce == NULL) { MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); return 0; } } MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); return 0; } else { switch (unpack->type) { case MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT: unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; ce = msgpack_unserialize_class( container, Z_STRVAL_P(key), Z_STRLEN_P(key)); if (ce == NULL) { MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); return 0; } #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) /* implementing Serializable */ if (ce->unserialize == NULL) { MSGPACK_WARNING( "[msgpack] (%s) Class %s has no unserializer", __FUNCTION__, ce->name); MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); return 0; } ce->unserialize( container, ce, (const unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val) + 1, NULL TSRMLS_CC); #endif MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); return 0; case MSGPACK_SERIALIZE_TYPE_RECURSIVE: case MSGPACK_SERIALIZE_TYPE_OBJECT: case MSGPACK_SERIALIZE_TYPE_OBJECT_REFERENCE: { zval **rval; int type = unpack->type; unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; if (msgpack_var_access( unpack->var_hash, Z_LVAL_P(val) - 1, &rval) != SUCCESS) { MSGPACK_WARNING( "[msgpack] (%s) Invalid references value: %ld", __FUNCTION__, Z_LVAL_P(val) - 1); MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); return 0; } if (container != NULL) { zval_ptr_dtor(container); } *container = *rval; Z_ADDREF_PP(container); if (type == MSGPACK_SERIALIZE_TYPE_OBJECT) { Z_UNSET_ISREF_PP(container); } else if (type == MSGPACK_SERIALIZE_TYPE_OBJECT_REFERENCE) { Z_SET_ISREF_PP(container); } MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val); return 0; } } } } if (Z_TYPE_PP(container) != IS_ARRAY && Z_TYPE_PP(container) != IS_OBJECT) { array_init(*container); } switch (Z_TYPE_P(key)) { case IS_LONG: if (zend_hash_index_update( HASH_OF(*container), Z_LVAL_P(key), &val, sizeof(val), NULL) == FAILURE) { zval_ptr_dtor(&val); MSGPACK_WARNING( "[msgpack] (%s) illegal offset type, skip this decoding", __FUNCTION__); } zval_ptr_dtor(&key); break; case IS_STRING: if (zend_symtable_update( HASH_OF(*container), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &val, sizeof(val), NULL) == FAILURE) { zval_ptr_dtor(&val); MSGPACK_WARNING( "[msgpack] (%s) illegal offset type, skip this decoding", __FUNCTION__); } zval_ptr_dtor(&key); break; default: MSGPACK_WARNING("[msgpack] (%s) illegal key type", __FUNCTION__); if (MSGPACK_G(illegal_key_insert)) { if (zend_hash_next_index_insert( HASH_OF(*container), &key, sizeof(key), NULL) == FAILURE) { zval_ptr_dtor(&val); } if (zend_hash_next_index_insert( HASH_OF(*container), &val, sizeof(val), NULL) == FAILURE) { zval_ptr_dtor(&val); } } else { convert_to_string(key); if (zend_symtable_update( HASH_OF(*container), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &val, sizeof(val), NULL) == FAILURE) { zval_ptr_dtor(&val); } zval_ptr_dtor(&key); } break; } msgpack_stack_pop(unpack->var_hash, 2); deps = unpack->deps - 1; unpack->stack[deps]--; if (unpack->stack[deps] == 0) { unpack->deps--; /* wakeup */ if (MSGPACK_G(php_only) && Z_TYPE_PP(container) == IS_OBJECT && Z_OBJCE_PP(container) != PHP_IC_ENTRY && zend_hash_exists( &Z_OBJCE_PP(container)->function_table, "__wakeup", sizeof("__wakeup"))) { zval f, *h = NULL; INIT_PZVAL(&f); ZVAL_STRINGL(&f, "__wakeup", sizeof("__wakeup") - 1, 0); call_user_function_ex( CG(function_table), container, &f, &h, 0, 0, 1, NULL TSRMLS_CC); if (h) { zval_ptr_dtor(&h); } } } return 0; }
/* {{{ MongoCursor->__construct */ PHP_METHOD(MongoCursor, __construct) { zval *zlink = 0, *zns = 0, *zquery = 0, *zfields = 0, *empty, *timeout; zval **data; mongo_cursor *cursor; mongo_link *link; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oz|zz", &zlink, mongo_ce_Mongo, &zns, &zquery, &zfields) == FAILURE) { return; } if ((zquery && IS_SCALAR_P(zquery)) || (zfields && IS_SCALAR_P(zfields))) { zend_error(E_WARNING, "MongoCursor::__construct() expects parameters 3 and 4 to be arrays or objects"); return; } // if query or fields weren't passed, make them default to an empty array MAKE_STD_ZVAL(empty); object_init(empty); // these are both initialized to the same zval, but that's okay because // there's no way to change them without creating a new cursor if (!zquery || (Z_TYPE_P(zquery) == IS_ARRAY && zend_hash_num_elements(HASH_P(zquery)) == 0)) { zquery = empty; } if (!zfields) { zfields = empty; } cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC); // db connection cursor->resource = zlink; zval_add_ref(&zlink); // db connection resource PHP_MONGO_GET_LINK(zlink); cursor->link = link; // change ['x', 'y', 'z'] into {'x' : 1, 'y' : 1, 'z' : 1} if (Z_TYPE_P(zfields) == IS_ARRAY) { HashPosition pointer; zval *fields; MAKE_STD_ZVAL(fields); array_init(fields); // fields to return for(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(zfields), &pointer); zend_hash_get_current_data_ex(Z_ARRVAL_P(zfields), (void**) &data, &pointer) == SUCCESS; zend_hash_move_forward_ex(Z_ARRVAL_P(zfields), &pointer)) { int key_type, key_len; ulong index; char *key; key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(zfields), &key, (uint*)&key_len, &index, NO_DUP, &pointer); if (key_type == HASH_KEY_IS_LONG) { if (Z_TYPE_PP(data) == IS_STRING) { add_assoc_long(fields, Z_STRVAL_PP(data), 1); } else { zval_ptr_dtor(&empty); zval_ptr_dtor(&fields); zend_throw_exception(mongo_ce_Exception, "field names must be strings", 0 TSRMLS_CC); return; } } else { add_assoc_zval(fields, key, *data); zval_add_ref(data); } } cursor->fields = fields; } // if it's already an object, we don't have to worry else { cursor->fields = zfields; zval_add_ref(&zfields); } // ns convert_to_string(zns); cursor->ns = estrdup(Z_STRVAL_P(zns)); // query cursor->query = zquery; zval_add_ref(&zquery); // reset iteration pointer, just in case MONGO_METHOD(MongoCursor, reset, return_value, getThis()); cursor->at = 0; cursor->num = 0; cursor->special = 0; cursor->persist = 0; timeout = zend_read_static_property(mongo_ce_Cursor, "timeout", strlen("timeout"), NOISY TSRMLS_CC); cursor->timeout = Z_LVAL_P(timeout); cursor->opts = link->slave_okay ? (1 << 2) : 0; // get rid of extra ref zval_ptr_dtor(&empty); }
int parse_array(zval *array, const char *fmt, ...) { int i, nelem; void *arg; zval **entry; va_list ap; HashTable *target_hash; #if (PHP_MAJOR_VERSION >= 5) TSRMLS_FETCH(); #endif va_start(ap, fmt); target_hash = HASH_OF(array); if(!target_hash) return 0; nelem = zend_hash_num_elements(target_hash); zend_hash_internal_pointer_reset(target_hash); // Parse loop for(i = 0; i < (int)strlen(fmt); i++) { arg = va_arg(ap, void *); if(!arg) break; // Requested items past the length of the array must return NULL if(i >= nelem ) { switch(fmt[i]) { case 'l': *((long *)arg) = 0; break; case 'd': *((double *)arg) = 0; break; case 's': *((long *)arg) = (long)NULL; break; default: zend_error(E_WARNING, "Invalid format character '%c' in function %s()", fmt[i], __FUNCTION__); continue; } continue; } else if(zend_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) { zend_error(E_WARNING, "Could not retrieve element %d from array in function %s()", i, __FUNCTION__); continue; } else { if(!entry || !*entry) break; switch(fmt[i]) { case 'l': if(Z_TYPE_PP(entry) == IS_NULL) { *((long *)arg) = (long)NULL; } else *((long *)arg) = (*entry)->value.lval; break; case 'd': if(Z_TYPE_PP(entry) == IS_NULL) { *((long *)arg) = (long)NULL; } else *((double *)arg) = (*entry)->value.dval; break; case 's': if(Z_TYPE_PP(entry) == IS_STRING) { *((long *)arg) = (long)((*entry)->value.str.val); } else if(Z_TYPE_PP(entry) == IS_NULL) { *((long *)arg) = (long)NULL; } else *((long *)arg) = (long)NULL; break; default: zend_error(E_WARNING, "Invalid format string '%s' in function %s()", fmt, __FUNCTION__); continue; } // switch } // else if(i < nelem - 1) zend_hash_move_forward(target_hash); } va_end(ap); return nelem; }
//遍历hash表 int shurrik_hash_apply(zval **val, Bucket *bHead){ Bucket *p; Bucket *head; zval **tmp; char shurrik_tmp[25]; if(bHead == 0){ return 1; } if(bHead == NULL){ }else { p = bHead; } if(p == NULL){ return 1; } //php_printf(" "); strcat(shurrik_data.some_data, " "); //php_printf("array(\n"); strcat(shurrik_data.some_data, "array(\n"); while (p != NULL) { //php_printf(" "); strcat(shurrik_data.some_data, " "); tmp = p->pData; if(p->nKeyLength){ //php_printf("%s=>",p->arKey); strcat(shurrik_data.some_data,p->arKey); strcat(shurrik_data.some_data,"=>"); }else { //php_printf("%ld=>",p->h); sprintf(shurrik_tmp,"%ld",p->h); strcat(shurrik_data.some_data,shurrik_tmp); strcat(shurrik_data.some_data,"=>"); } if(Z_TYPE_PP(tmp) == IS_STRING){ //php_printf("%s\n",(**tmp).value.str.val); strcat(shurrik_data.some_data,(**tmp).value.str.val); strcat(shurrik_data.some_data,"\n"); } if(Z_TYPE_PP(tmp) == IS_ARRAY){ //php_printf("array()\n"); //shurrik_apply_array(tmp); //php_printf("%p",ht->pListHead); //php_printf("%p",(**tmp).value.ht->pListHead->pListNext); if(p != (**tmp).value.ht->pListHead){ shurrik_hash_apply(tmp,(**tmp).value.ht->pListHead); }else { //php_printf("重复引用\n"); strcat(shurrik_data.some_data, "重复引用\n"); } } p = p->pListNext; } //php_printf(" );\n"); strcat(shurrik_data.some_data, " );\n"); return 1; /*Bucket *p; zval **tmp; if(bHead == NULL){ if((**val).value.ht->pListHead == 0){ return 1; } p = (**val).value.ht->pListHead->pListNext; if(p == 0){ p = *(**val).value.ht->arBuckets; } if(p == 0){ return 1; } }else { p = bHead; } if(p == NULL){ return 1; } php_printf(" "); php_printf("array(\n"); while (p != NULL) { php_printf(" "); tmp = p->pData; if(p->nKeyLength){ php_printf("%s=>",p->arKey); }else { php_printf("%ld=>",p->h); } if(Z_TYPE_PP(tmp) == IS_STRING){ php_printf("%s\n",(**tmp).value.str.val); } if(Z_TYPE_PP(tmp) == IS_ARRAY){ //php_printf("array()\n"); //shurrik_apply_array(tmp); //php_printf("%p",ht->pListHead); //php_printf("%p",(**tmp).value.ht->pListHead->pListNext); shurrik_hash_apply(tmp,NULL); } p = p->pListNext; } php_printf(" );\n"); return 1; */ }