Пример #1
0
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 = &param->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(&param->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(&param->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(&param->parameter);
			param->param_type = PDO_PARAM_STR;
			convert_to_boolean(&param->parameter);
			ZVAL_STRINGL(&param->parameter, Z_TYPE_P(&param->parameter) == IS_TRUE ? "t" : "f", 1);
		}
	}
	return 1;
}
Пример #2
0
/* {{{ 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;

}
Пример #3
0
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;
}