Open a file or a URL and return a file pointer */
PHP_NAMED_FUNCTION(php_if_fopen)
{
+ zval **ppfilename;
char *filename, *mode;
int filename_len, mode_len;
- zend_uchar filename_type;
zend_bool use_include_path = 0;
zval *zcontext = NULL;
php_stream *stream;
php_stream_context *context = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ts|br", &filename, &filename_len, &filename_type,
- &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs|br", &ppfilename, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
RETURN_FALSE;
}
context = php_stream_context_from_zval(zcontext, 0);
- if (filename_type == IS_UNICODE) {
- if (php_stream_path_encode(NULL, &filename, &filename_len, (UChar*)filename, filename_len, REPORT_ERRORS, context) == FAILURE) {
- RETURN_FALSE;
- }
+ if (FAILURE == php_stream_path_param_encode(ppfilename, &filename, &filename_len, REPORT_ERRORS, context)) {
+ RETURN_FALSE;
}
+
stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | REPORT_ERRORS, NULL, context);
- if (filename_type == IS_UNICODE) {
- efree(filename);
- }
if (stream == NULL) {
RETURN_FALSE;
}
END_EXTERN_C()
+#define php_stream_path_param_encode(ppzval, ppath, ppath_len, options, context) \
+ _php_stream_path_param_encode((ppzval), (ppath), (ppath_len), (options), (context) TSRMLS_CC)
+static inline int _php_stream_path_param_encode(zval **ppzval, char **ppath, int *ppath_len, int options, php_stream_context *context TSRMLS_DC)
+{
+ if (Z_TYPE_PP(ppzval) == IS_UNICODE) {
+ zval *zpath;
+ char *path;
+ int path_len;
+
+ /* Convert the path and put it into a fresh new zval */
+ if (FAILURE == php_stream_path_encode(NULL, &path, &path_len, Z_USTRVAL_PP(ppzval), Z_USTRLEN_PP(ppzval), options, context)) {
+ return FAILURE;
+ }
+ MAKE_STD_ZVAL(zpath);
+ ZVAL_STRINGL(zpath, path, path_len, 0);
+ zpath->is_ref = 0;
+ zpath->refcount = 1;
+
+ /* Replace the param stack with the new zval */
+ zval_ptr_dtor(ppzval);
+ *ppzval = zpath;
+ } else if (Z_TYPE_PP(ppzval) != IS_STRING) {
+ if ((*ppzval)->is_ref ||
+ (*ppzval)->refcount > 1) {
+ zval *zpath;
+
+ /* Produce a new zval of type string */
+ MAKE_STD_ZVAL(zpath);
+ *zpath = **ppzval;
+ zval_copy_ctor(zpath);
+ convert_to_string(zpath);
+ zpath->is_ref = 0;
+ zpath->refcount = 1;
+
+ /* Replace the param stack with it */
+ zval_ptr_dtor(ppzval);
+ *ppzval = zpath;
+ } else {
+ /* Convert the value on the param stack directly */
+ convert_to_string(*ppzval);
+ }
+ }
+
+ /* Populate convenience params if requested */
+ if (ppath) {
+ *ppath = Z_STRVAL_PP(ppzval);
+ }
+ if (ppath_len) {
+ *ppath_len = Z_STRLEN_PP(ppzval);
+ }
+
+ return SUCCESS;
+}
+
+
/* Flags for mkdir method in wrapper ops */
#define PHP_STREAM_MKDIR_RECURSIVE 1
/* define REPORT ERRORS 8 (below) */