static void phalcon_config_adapter_ini_update_zval_directive(zval *arr, zval *section, zval *directive, zval *value) { zval t1 = {}, tmp = {}, index = {}; int i, n; assert(Z_TYPE_P(arr) == IS_ARRAY); assert(Z_TYPE_P(directive) == IS_ARRAY); n = zend_hash_num_elements(Z_ARRVAL_P(directive)); assert(n > 1); if (!phalcon_array_isset_fetch(&t1, arr, section, 0)) { array_init(&t1); phalcon_array_update_zval(arr, section, &t1, 0); } else if (Z_TYPE_P(&t1) != IS_ARRAY) { convert_to_array_ex(&t1); } ZVAL_COPY(&tmp, &t1); for (i = 0; i < n - 1; i++) { zval t2 = {}; phalcon_array_fetch_long(&index, directive, i, PH_NOISY); if (!phalcon_array_isset_fetch(&t2, &tmp, &index, 0)) { array_init(&t2); phalcon_array_update_zval(&tmp, &index, &t2, 0); } else if (Z_TYPE(t2) != IS_ARRAY) { convert_to_array_ex(&t2); } ZVAL_COPY(&tmp, &t2); } phalcon_array_fetch_long(&index, directive, n - 1, PH_NOISY); phalcon_array_update_zval(&tmp, &index, value, 0); }
/* php_formatted_print() {{{ * New sprintf implementation for PHP. * * Modifiers: * * " " pad integers with spaces * "-" left adjusted field * n field size * "."n precision (floats only) * "+" Always place a sign (+ or -) in front of a number * * Type specifiers: * * "%" literal "%", modifiers are ignored. * "b" integer argument is printed as binary * "c" integer argument is printed as a single character * "d" argument is an integer * "f" the argument is a float * "o" integer argument is printed as octal * "s" argument is a string * "x" integer argument is printed as lowercase hexadecimal * "X" integer argument is printed as uppercase hexadecimal * */ static char * php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC) { zval ***args, **z_format; int argc, size = 240, inpos = 0, outpos = 0, temppos; int alignment, currarg, adjusting, argnum, width, precision; char *format, *result, padding; int always_sign; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) { return NULL; } /* verify the number of args */ if ((use_array && argc != (2 + format_offset)) || (!use_array && argc < (1 + format_offset))) { efree(args); WRONG_PARAM_COUNT_WITH_RETVAL(NULL); } if (use_array) { int i = 1; zval ***newargs; zval **array; z_format = args[format_offset]; array = args[1 + format_offset]; SEPARATE_ZVAL(array); convert_to_array_ex(array); argc = 1 + zend_hash_num_elements(Z_ARRVAL_PP(array)); newargs = (zval ***)safe_emalloc(argc, sizeof(zval *), 0); newargs[0] = z_format; for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(array)); zend_hash_get_current_data(Z_ARRVAL_PP(array), (void **)&newargs[i++]) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_PP(array))); efree(args); args = newargs; format_offset = 0; } convert_to_string_ex(args[format_offset]); format = Z_STRVAL_PP(args[format_offset]); result = emalloc(size); currarg = 1; while (inpos<Z_STRLEN_PP(args[format_offset])) { int expprec = 0, multiuse = 0; zval *tmp; PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos])); PRINTF_DEBUG(("sprintf: outpos=%d\n", outpos)); if (format[inpos] != '%') { php_sprintf_appendchar(&result, &outpos, &size, format[inpos++] TSRMLS_CC); } else if (format[inpos + 1] == '%') { php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC); inpos += 2; } else { /* starting a new format specifier, reset variables */ alignment = ALIGN_RIGHT; adjusting = 0; padding = ' '; always_sign = 0; inpos++; /* skip the '%' */ PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n", format[inpos], inpos)); if (isascii((int)format[inpos]) && !isalpha((int)format[inpos])) { /* first look for argnum */ temppos = inpos; while (isdigit((int)format[temppos])) temppos++; if (format[temppos] == '$') { argnum = php_sprintf_getnumber(format, &inpos); if (argnum <= 0) { efree(result); efree(args); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument number must be greater than zero"); return NULL; } multiuse = 1; inpos++; /* skip the '$' */ } else { argnum = currarg++; } argnum += format_offset; /* after argnum comes modifiers */ PRINTF_DEBUG(("sprintf: looking for modifiers\n" "sprintf: now looking at '%c', inpos=%d\n", format[inpos], inpos)); for (;; inpos++) { if (format[inpos] == ' ' || format[inpos] == '0') { padding = format[inpos]; } else if (format[inpos] == '-') { alignment = ALIGN_LEFT; /* space padding, the default */ } else if (format[inpos] == '+') { always_sign = 1; } else if (format[inpos] == '\'') { padding = format[++inpos]; } else { PRINTF_DEBUG(("sprintf: end of modifiers\n")); break; } } PRINTF_DEBUG(("sprintf: padding='%c'\n", padding)); PRINTF_DEBUG(("sprintf: alignment=%s\n", (alignment == ALIGN_LEFT) ? "left" : "right")); /* after modifiers comes width */ if (isdigit((int)format[inpos])) { PRINTF_DEBUG(("sprintf: getting width\n")); if ((width = php_sprintf_getnumber(format, &inpos)) < 0) { efree(result); efree(args); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Width must be greater than zero and less than %d", INT_MAX); return NULL; } adjusting |= ADJ_WIDTH; } else { width = 0; } PRINTF_DEBUG(("sprintf: width=%d\n", width)); /* after width and argnum comes precision */ if (format[inpos] == '.') { inpos++; PRINTF_DEBUG(("sprintf: getting precision\n")); if (isdigit((int)format[inpos])) { if ((precision = php_sprintf_getnumber(format, &inpos)) < 0) { efree(result); efree(args); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX); return NULL; } adjusting |= ADJ_PRECISION; expprec = 1; } else { precision = 0; } } else { precision = 0; } PRINTF_DEBUG(("sprintf: precision=%d\n", precision)); } else { width = precision = 0; argnum = currarg++ + format_offset; } if (argnum >= argc) { efree(result); efree(args); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments"); return NULL; } if (format[inpos] == 'l') { inpos++; } PRINTF_DEBUG(("sprintf: format character='%c'\n", format[inpos])); /* now we expect to find a type specifier */ if (multiuse) { MAKE_STD_ZVAL(tmp); *tmp = **(args[argnum]); INIT_PZVAL(tmp); zval_copy_ctor(tmp); } else { SEPARATE_ZVAL(args[argnum]); tmp = *(args[argnum]); } switch (format[inpos]) { case 's': { zval *var, var_copy; int use_copy; zend_make_printable_zval(tmp, &var_copy, &use_copy); if (use_copy) { var = &var_copy; } else { var = tmp; } php_sprintf_appendstring(&result, &outpos, &size, Z_STRVAL_P(var), width, precision, padding, alignment, Z_STRLEN_P(var), 0, expprec, 0); if (use_copy) { zval_dtor(&var_copy); } break; } case 'd': convert_to_long(tmp); php_sprintf_appendint(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, always_sign); break; case 'u': convert_to_long(tmp); php_sprintf_appenduint(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment); break; case 'g': case 'G': case 'e': case 'E': case 'f': case 'F': convert_to_double(tmp); php_sprintf_appenddouble(&result, &outpos, &size, Z_DVAL_P(tmp), width, padding, alignment, precision, adjusting, format[inpos], always_sign TSRMLS_CC); break; case 'c': convert_to_long(tmp); php_sprintf_appendchar(&result, &outpos, &size, (char) Z_LVAL_P(tmp) TSRMLS_CC); break; case 'o': convert_to_long(tmp); php_sprintf_append2n(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, 3, hexchars, expprec); break; case 'x': convert_to_long(tmp); php_sprintf_append2n(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, 4, hexchars, expprec); break; case 'X': convert_to_long(tmp); php_sprintf_append2n(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, 4, HEXCHARS, expprec); break; case 'b': convert_to_long(tmp); php_sprintf_append2n(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, 1, hexchars, expprec); break; case '%': php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC); break; default: break; } if (multiuse) { zval_ptr_dtor(&tmp); } inpos++; } } efree(args); /* possibly, we have to make sure we have room for the terminating null? */ result[outpos]=0; *len = outpos; return result; }
static int php_do_mcast_opt(php_socket *php_sock, int level, int optname, zval *arg4) { HashTable *opt_ht; unsigned int if_index; int retval; int (*mcast_req_fun)(php_socket *, int, struct sockaddr *, socklen_t, unsigned); #ifdef HAS_MCAST_EXT int (*mcast_sreq_fun)(php_socket *, int, struct sockaddr *, socklen_t, struct sockaddr *, socklen_t, unsigned); #endif switch (optname) { case PHP_MCAST_JOIN_GROUP: mcast_req_fun = &php_mcast_join; goto mcast_req_fun; case PHP_MCAST_LEAVE_GROUP: { php_sockaddr_storage group = {0}; socklen_t glen; mcast_req_fun = &php_mcast_leave; mcast_req_fun: convert_to_array_ex(arg4); opt_ht = Z_ARRVAL_P(arg4); if (php_get_address_from_array(opt_ht, "group", php_sock, &group, &glen) == FAILURE) { return FAILURE; } if (php_get_if_index_from_array(opt_ht, "interface", php_sock, &if_index) == FAILURE) { return FAILURE; } retval = mcast_req_fun(php_sock, level, (struct sockaddr*)&group, glen, if_index); break; } #ifdef HAS_MCAST_EXT case PHP_MCAST_BLOCK_SOURCE: mcast_sreq_fun = &php_mcast_block_source; goto mcast_sreq_fun; case PHP_MCAST_UNBLOCK_SOURCE: mcast_sreq_fun = &php_mcast_unblock_source; goto mcast_sreq_fun; case PHP_MCAST_JOIN_SOURCE_GROUP: mcast_sreq_fun = &php_mcast_join_source; goto mcast_sreq_fun; case PHP_MCAST_LEAVE_SOURCE_GROUP: { php_sockaddr_storage group = {0}, source = {0}; socklen_t glen, slen; mcast_sreq_fun = &php_mcast_leave_source; mcast_sreq_fun: convert_to_array_ex(arg4); opt_ht = Z_ARRVAL_P(arg4); if (php_get_address_from_array(opt_ht, "group", php_sock, &group, &glen) == FAILURE) { return FAILURE; } if (php_get_address_from_array(opt_ht, "source", php_sock, &source, &slen) == FAILURE) { return FAILURE; } if (php_get_if_index_from_array(opt_ht, "interface", php_sock, &if_index) == FAILURE) { return FAILURE; } retval = mcast_sreq_fun(php_sock, level, (struct sockaddr*)&group, glen, (struct sockaddr*)&source, slen, if_index); break; } #endif default: php_error_docref(NULL, E_WARNING, "unexpected option in php_do_mcast_opt (level %d, option %d). " "This is a bug.", level, optname); return FAILURE; } if (retval != 0) { if (retval != -2) { /* error, but message already emitted */ PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno); } return FAILURE; } return SUCCESS; }