static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type) { pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data; if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED && param->is_param) { switch (event_type) { case PDO_PARAM_EVT_FREE: if (param->driver_data) { efree(param->driver_data); } break; case PDO_PARAM_EVT_NORMALIZE: /* decode name from $1, $2 into 0, 1 etc. */ if (param->name) { if (param->name->val[0] == '$') { ZEND_ATOL(param->paramno, param->name->val + 1); } else { /* resolve parameter name to rewritten name */ char *namevar; if (stmt->bound_param_map && (namevar = zend_hash_find_ptr(stmt->bound_param_map, param->name)) != NULL) { ZEND_ATOL(param->paramno, namevar + 1); param->paramno--; } else { pdo_raise_impl_error(stmt->dbh, stmt, "HY093", param->name->val); return 0; } } } break; case PDO_PARAM_EVT_ALLOC: case PDO_PARAM_EVT_EXEC_POST: case PDO_PARAM_EVT_FETCH_PRE: case PDO_PARAM_EVT_FETCH_POST: /* work is handled by EVT_NORMALIZE */ return 1; case PDO_PARAM_EVT_EXEC_PRE: if (!stmt->bound_param_map) { return 0; } if (!S->param_values) { S->param_values = ecalloc( zend_hash_num_elements(stmt->bound_param_map), sizeof(char*)); S->param_lengths = ecalloc( zend_hash_num_elements(stmt->bound_param_map), sizeof(int)); S->param_formats = ecalloc( zend_hash_num_elements(stmt->bound_param_map), sizeof(int)); S->param_types = ecalloc( zend_hash_num_elements(stmt->bound_param_map), sizeof(Oid)); } if (param->paramno >= 0) { zval *parameter; if (param->paramno >= zend_hash_num_elements(stmt->bound_params)) { pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined"); return 0; } if (Z_ISREF(param->parameter)) { parameter = Z_REFVAL(param->parameter); } else { parameter = ¶m->parameter; } if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && Z_TYPE_P(parameter) == IS_RESOURCE) { php_stream *stm; php_stream_from_zval_no_verify(stm, parameter); if (stm) { if (php_stream_is(stm, &pdo_pgsql_lob_stream_ops)) { struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract; pdo_pgsql_bound_param *P = param->driver_data; if (P == NULL) { P = ecalloc(1, sizeof(*P)); param->driver_data = P; } P->oid = htonl(self->oid); S->param_values[param->paramno] = (char*)&P->oid; S->param_lengths[param->paramno] = sizeof(P->oid); S->param_formats[param->paramno] = 1; S->param_types[param->paramno] = OIDOID; return 1; } else { zend_string *str = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0); if (str != NULL) { //??SEPARATE_ZVAL_IF_NOT_REF(¶m->parameter); ZVAL_STR(parameter, str); } else { ZVAL_EMPTY_STRING(parameter); } } } else { /* expected a stream resource */ pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105"); return 0; } } if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL || Z_TYPE_P(parameter) == IS_NULL) { S->param_values[param->paramno] = NULL; S->param_lengths[param->paramno] = 0; } else if (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE) { S->param_values[param->paramno] = Z_TYPE_P(parameter) == IS_TRUE ? "t" : "f"; S->param_lengths[param->paramno] = 1; S->param_formats[param->paramno] = 0; } else { //SEPARATE_ZVAL_IF_NOT_REF(¶m->parameter); convert_to_string_ex(parameter); S->param_values[param->paramno] = Z_STRVAL_P(parameter); S->param_lengths[param->paramno] = Z_STRLEN_P(parameter); S->param_formats[param->paramno] = 0; } if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) { S->param_types[param->paramno] = 0; S->param_formats[param->paramno] = 1; } else { S->param_types[param->paramno] = 0; } } break; } } else if (param->is_param) { /* We need to manually convert to a pg native boolean value */ if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && ((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) { SEPARATE_ZVAL(¶m->parameter); param->param_type = PDO_PARAM_STR; convert_to_boolean(¶m->parameter); ZVAL_STRINGL(¶m->parameter, Z_TYPE_P(¶m->parameter) == IS_TRUE ? "t" : "f", 1); } } return 1; }
/* {{{ php_stream_cast */ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err) { int flags = castas & PHP_STREAM_CAST_MASK; castas &= ~PHP_STREAM_CAST_MASK; /* synchronize our buffer (if possible) */ if (ret && castas != PHP_STREAM_AS_FD_FOR_SELECT) { php_stream_flush(stream); if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { zend_off_t dummy; stream->ops->seek(stream, stream->position, SEEK_SET, &dummy); stream->readpos = stream->writepos = 0; } } /* filtered streams can only be cast as stdio, and only when fopencookie is present */ if (castas == PHP_STREAM_AS_STDIO) { if (stream->stdiocast) { if (ret) { *(FILE**)ret = stream->stdiocast; } goto exit_success; } /* if the stream is a stdio stream let's give it a chance to respond * first, to avoid doubling up the layers of stdio with an fopencookie */ if (php_stream_is(stream, PHP_STREAM_IS_STDIO) && stream->ops->cast && !php_stream_is_filtered(stream) && stream->ops->cast(stream, castas, ret) == SUCCESS ) { goto exit_success; } #if HAVE_FOPENCOOKIE /* if just checking, say yes we can be a FILE*, but don't actually create it yet */ if (ret == NULL) { goto exit_success; } { char fixed_mode[5]; php_stream_mode_sanitize_fdopen_fopencookie(stream, fixed_mode); *(FILE**)ret = fopencookie(stream, fixed_mode, PHP_STREAM_COOKIE_FUNCTIONS); } if (*ret != NULL) { zend_off_t pos; stream->fclose_stdiocast = PHP_STREAM_FCLOSE_FOPENCOOKIE; /* If the stream position is not at the start, we need to force * the stdio layer to believe it's real location. */ pos = php_stream_tell(stream); if (pos > 0) { zend_fseek(*ret, pos, SEEK_SET); } goto exit_success; } /* must be either: a) programmer error b) no memory -> lets bail */ php_error_docref(NULL, E_ERROR, "fopencookie failed"); return FAILURE; #endif if (!php_stream_is_filtered(stream) && stream->ops->cast && stream->ops->cast(stream, castas, NULL) == SUCCESS) { if (FAILURE == stream->ops->cast(stream, castas, ret)) { return FAILURE; } goto exit_success; } else if (flags & PHP_STREAM_CAST_TRY_HARD) { php_stream *newstream; newstream = php_stream_fopen_tmpfile(); if (newstream) { int retcopy = php_stream_copy_to_stream_ex(stream, newstream, PHP_STREAM_COPY_ALL, NULL); if (retcopy != SUCCESS) { php_stream_close(newstream); } else { int retcast = php_stream_cast(newstream, castas | flags, (void **)ret, show_err); if (retcast == SUCCESS) { rewind(*(FILE**)ret); } /* do some specialized cleanup */ if ((flags & PHP_STREAM_CAST_RELEASE)) { php_stream_free(stream, PHP_STREAM_FREE_CLOSE_CASTED); } /* TODO: we probably should be setting .stdiocast and .fclose_stdiocast or * we may be leaking the FILE*. Needs investigation, though. */ return retcast; } } } } if (php_stream_is_filtered(stream)) { php_error_docref(NULL, E_WARNING, "cannot cast a filtered stream on this system"); return FAILURE; } else if (stream->ops->cast && stream->ops->cast(stream, castas, ret) == SUCCESS) { goto exit_success; } if (show_err) { /* these names depend on the values of the PHP_STREAM_AS_XXX defines in php_streams.h */ static const char *cast_names[4] = { "STDIO FILE*", "File Descriptor", "Socket Descriptor", "select()able descriptor" }; php_error_docref(NULL, E_WARNING, "cannot represent a stream of type %s as a %s", stream->ops->label, cast_names[castas]); } return FAILURE; exit_success: if ((stream->writepos - stream->readpos) > 0 && stream->fclose_stdiocast != PHP_STREAM_FCLOSE_FOPENCOOKIE && (flags & PHP_STREAM_CAST_INTERNAL) == 0 ) { /* the data we have buffered will be lost to the third party library that * will be accessing the stream. Emit a warning so that the end-user will * know that they should try something else */ php_error_docref(NULL, E_WARNING, ZEND_LONG_FMT " bytes of buffered data lost during stream conversion!", (zend_long)(stream->writepos - stream->readpos)); } if (castas == PHP_STREAM_AS_STDIO && ret) { stream->stdiocast = *(FILE**)ret; } if (flags & PHP_STREAM_CAST_RELEASE) { php_stream_free(stream, PHP_STREAM_FREE_CLOSE_CASTED); } return SUCCESS; }
int php_imagick_read_image_using_php_streams(php_imagick_object *intern, int type, char *filename, int filename_len TSRMLS_DC) { php_stream *stream; MagickBooleanType status; FILE *fp; #if ZEND_MODULE_API_NO > 20060613 zend_error_handling error_handling; #endif #if ZEND_MODULE_API_NO > 20060613 zend_replace_error_handling(EH_THROW, php_imagick_exception_class_entry, &error_handling TSRMLS_CC); #else php_set_error_handling(EH_THROW, php_imagick_exception_class_entry TSRMLS_CC); #endif stream = php_stream_open_wrapper(filename, "rb", (ENFORCE_SAFE_MODE|IGNORE_PATH) & ~REPORT_ERRORS, NULL); if (!stream) { goto return_error; } if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO|PHP_STREAM_CAST_INTERNAL) == FAILURE) { goto return_error; } if (php_stream_cast(stream, PHP_STREAM_AS_STDIO|PHP_STREAM_CAST_INTERNAL, (void*)&fp, 0) == FAILURE) { goto return_error; } #if ZEND_MODULE_API_NO > 20060613 zend_restore_error_handling(&error_handling TSRMLS_CC); #else php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); #endif if (type == 1) { status = MagickReadImageFile(intern->magick_wand, fp); } else { status = MagickPingImageFile(intern->magick_wand, fp); } if (status == MagickFalse) { php_stream_close(stream); return IMAGICK_READ_WRITE_UNDERLYING_LIBRARY; } if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) { char *absolute = expand_filepath(filename, NULL TSRMLS_CC); MagickSetImageFilename(intern->magick_wand, absolute); efree(absolute); } else { /* Set to empty filename, otherwise it will point to MAGICK_TEMP/magick-XXXXX */ MagickSetImageFilename(intern->magick_wand, ""); } php_stream_close(stream); if (status == MagickFalse) { return IMAGICK_READ_WRITE_UNDERLYING_LIBRARY; } IMAGICK_CORRECT_ITERATOR_POSITION(intern); return IMAGICK_READ_WRITE_NO_ERROR; return_error: #if ZEND_MODULE_API_NO > 20060613 zend_restore_error_handling(&error_handling TSRMLS_CC); #else php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); #endif if (stream) php_stream_close(stream); return IMAGICK_READ_WRITE_UNDERLYING_LIBRARY; }