Beispiel #1
1
static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mimetype_emu) /* {{{ */
{
	zend_long options = 0;
	char *ret_val = NULL, *buffer = NULL;
	size_t buffer_len;
	php_fileinfo *finfo = NULL;
	zval *zfinfo, *zcontext = NULL;
	zval *what;
	char mime_directory[] = "directory";

	struct magic_set *magic = NULL;
	FILEINFO_DECLARE_INIT_OBJECT(object)

	if (mimetype_emu) {

		/* mime_content_type(..) emulation */
		if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &what) == FAILURE) {
			return;
		}

		switch (Z_TYPE_P(what)) {
			case IS_STRING:
				buffer = Z_STRVAL_P(what);
				buffer_len = Z_STRLEN_P(what);
				mode = FILEINFO_MODE_FILE;
				break;

			case IS_RESOURCE:
				mode = FILEINFO_MODE_STREAM;
				break;

			default:
				php_error_docref(NULL, E_WARNING, "Can only process string or stream arguments");
				RETURN_FALSE;
		}

		magic = magic_open(MAGIC_MIME_TYPE);
		if (magic_load(magic, NULL) == -1) {
			php_error_docref(NULL, E_WARNING, "Failed to load magic database.");
			goto common;
		}
	} else if (object) {
		if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lr", &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
			RETURN_FALSE;
		}
		FILEINFO_FROM_OBJECT(finfo, object);
		magic = finfo->magic;
	} else {
		if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|lr", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
			RETURN_FALSE;
		}
		if ((finfo = (php_fileinfo *)zend_fetch_resource(Z_RES_P(zfinfo), "file_info", le_fileinfo)) == NULL) {
			RETURN_FALSE;
		}
		magic = finfo->magic;
	}

	/* Set options for the current file/buffer. */
	if (options) {
		FINFO_SET_OPTION(magic, options)
	}

	switch (mode) {
		case FILEINFO_MODE_BUFFER:
		{
			ret_val = (char *) magic_buffer(magic, buffer, buffer_len);
			break;
		}

		case FILEINFO_MODE_STREAM:
		{
				php_stream *stream;
				zend_off_t streampos;

				php_stream_from_zval_no_verify(stream, what);
				if (!stream) {
					goto common;
				}

				streampos = php_stream_tell(stream); /* remember stream position for restoration */
				php_stream_seek(stream, 0, SEEK_SET);

				ret_val = (char *) magic_stream(magic, stream);

				php_stream_seek(stream, streampos, SEEK_SET);
				break;
		}

		case FILEINFO_MODE_FILE:
		{
			/* determine if the file is a local file or remote URL */
			const char *tmp2;
			php_stream_wrapper *wrap;
			php_stream_statbuf ssb;

			if (buffer == NULL || !*buffer) {
				php_error_docref(NULL, E_WARNING, "Empty filename or path");
				RETVAL_FALSE;
				goto clean;
			}

			wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0);

			if (wrap) {
				php_stream *stream;
				php_stream_context *context = php_stream_context_from_zval(zcontext, 0);

#ifdef PHP_WIN32
				if (php_stream_stat_path_ex(buffer, 0, &ssb, context) == SUCCESS) {
					if (ssb.sb.st_mode & S_IFDIR) {
						ret_val = mime_directory;
						goto common;
					}
				}
#endif

#if PHP_API_VERSION < 20100412
				stream = php_stream_open_wrapper_ex(buffer, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
#else
				stream = php_stream_open_wrapper_ex(buffer, "rb", REPORT_ERRORS, NULL, context);
#endif

				if (!stream) {
					RETVAL_FALSE;
					goto clean;
				}

				if (php_stream_stat(stream, &ssb) == SUCCESS) {
					if (ssb.sb.st_mode & S_IFDIR) {
						ret_val = mime_directory;
					} else {
						ret_val = (char *)magic_stream(magic, stream);
					}
				}

				php_stream_close(stream);
			}
			break;
		}

		default:
			php_error_docref(NULL, E_WARNING, "Can only process string or stream arguments");
	}

common:
	if (ret_val) {
		RETVAL_STRING(ret_val);
	} else {
		php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
		RETVAL_FALSE;
	}

clean:
	if (mimetype_emu) {
		magic_close(magic);
	}

	/* Restore options */
	if (options) {
		FINFO_SET_OPTION(magic, finfo->options)
	}
	return;
}
Beispiel #2
0
/* {{{ flatfile_store
 */
int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC) {
	if (mode == FLATFILE_INSERT) {
		if (flatfile_findkey(dba, key_datum TSRMLS_CC)) {
			return 1;
		}
		php_stream_seek(dba->fp, 0L, SEEK_END);
		php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize);
		php_stream_flush(dba->fp);
		if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
			return -1;
		}
		php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize);
		php_stream_flush(dba->fp);
		if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
			return -1;
		}
	} else { /* FLATFILE_REPLACE */
		flatfile_delete(dba, key_datum TSRMLS_CC);
		php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize);
		php_stream_flush(dba->fp);
		if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) {
			return -1;
		}
		php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize);
		if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) {
			return -1;
		}
	}

	php_stream_flush(dba->fp);
	return 0;
}
Beispiel #3
0
static zval* _jsr_file_get_contents()
{
  TSRMLS_FETCH();
  
  zval *payload;

  MAKE_STD_ZVAL(payload);

  zend_bool use_include_path = 0;
  php_stream *stream;
  int len;
  long offset = -1;
  long maxlen = PHP_STREAM_COPY_ALL;
  zval *zcontext = NULL;
  php_stream_context *context = NULL;

  char *contents;

  

  context = php_stream_context_from_zval(zcontext, 0);

  stream = php_stream_open_wrapper_ex("php://input", "rb",
        (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS,
        NULL, context);
  
  if (!stream) {
    ZVAL_NULL(payload);
    php_stream_close(stream);
    return payload;
  }

  if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
    php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset);
    php_stream_close(stream);
    ZVAL_NULL(payload);
    return payload;
  }

  if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
#if PHP_API_VERSION < 20100412
    if (PG(magic_quotes_runtime)) {
      contents = php_addslashes(contents, len, &len, 1 TSRMLS_CC); 
    }
#endif
    ZVAL_STRINGL(payload, contents, len, 1);
    php_stream_close(stream);
    return payload;
  } else if (len == 0) {
    ZVAL_STRING(payload, "", 0);
    php_stream_close(stream);
    return payload;
  } else {
    ZVAL_NULL(payload);
    php_stream_close(stream);
    return payload;
  }
  
}
Beispiel #4
0
static size_t php_curl_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
{
	php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
	size_t didread = 0;
	
	if (curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending) {
		/* we need to read some more data */
		struct timeval tv;

		/* fire up the connection */
		if (curlstream->readbuffer.writepos == 0) {
			while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curlstream->multi, &curlstream->pending));
		}
		
		do {
			FD_ZERO(&curlstream->readfds);
			FD_ZERO(&curlstream->writefds);
			FD_ZERO(&curlstream->excfds);

			/* get the descriptors from curl */
			curl_multi_fdset(curlstream->multi, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &curlstream->maxfd);

			/* if we are in blocking mode, set a timeout */
			tv.tv_usec = 0;
			tv.tv_sec = 15; /* TODO: allow this to be configured from the script */

			/* wait for data */
			switch ((curlstream->maxfd < 0) ? 1 : 
					select(curlstream->maxfd + 1, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &tv)) {
				case -1:
					/* error */
					return 0;
				case 0:
					/* no data yet: timed-out */
					return 0;
				default:
					/* fetch the data */
					do {
						curlstream->mcode = curl_multi_perform(curlstream->multi, &curlstream->pending);
					} while (curlstream->mcode == CURLM_CALL_MULTI_PERFORM);
			}
		} while (curlstream->maxfd >= 0 &&
				curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending > 0);

	}

	/* if there is data in the buffer, try and read it */
	if (curlstream->readbuffer.writepos > 0 && curlstream->readbuffer.readpos < curlstream->readbuffer.writepos) {
		php_stream_seek(curlstream->readbuffer.buf, curlstream->readbuffer.readpos, SEEK_SET);
		didread = php_stream_read(curlstream->readbuffer.buf, buf, count);
		curlstream->readbuffer.readpos = php_stream_tell(curlstream->readbuffer.buf);
	}

	if (didread == 0) {
		stream->eof = 1;
	}
	
	return didread;
}
Beispiel #5
0
/* {{{ inifile_filter
 * copy from to dba while ignoring key name (group must equal)
 */
static int inifile_filter(inifile *dba, inifile *from, const key_type *key, zend_bool *found)
{
	size_t pos_start = 0, pos_next = 0, pos_curr;
	int ret = SUCCESS;
	line_type ln = {{NULL,NULL},{NULL}};

	php_stream_seek(from->fp, 0, SEEK_SET);
	php_stream_seek(dba->fp, 0, SEEK_END);
	while(inifile_read(from, &ln)) {
		switch(inifile_key_cmp(&ln.key, key)) {
		case 0:
			if (found) {
				*found = (zend_bool) 1;
			}
			pos_curr = php_stream_tell(from->fp);
			if (pos_start != pos_next) {
				php_stream_seek(from->fp, pos_start, SEEK_SET);
				if (SUCCESS != php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) {
					php_error_docref(NULL, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start);
					ret = FAILURE;
				}
				php_stream_seek(from->fp, pos_curr, SEEK_SET);
			}
			pos_next = pos_start = pos_curr;
			break;
		case 1:
			pos_next = php_stream_tell(from->fp);
			break;
		case 2:
			/* the function is meant to process only entries from same group */
			assert(0);
			break;
		}
	}
	if (pos_start != pos_next) {
		php_stream_seek(from->fp, pos_start, SEEK_SET);
		if (SUCCESS != php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) {
			php_error_docref(NULL, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start);
			ret = FAILURE;
		}
	}
	inifile_line_free(&ln);
	return ret;
}
Beispiel #6
0
static int stream_cookie_seeker(void *cookie, __off64_t *position, int whence)
{

	*position = php_stream_seek((php_stream *)cookie, (zend_off_t)*position, whence);

	if (*position == -1) {
		return -1;
	}
	return 0;
}
Beispiel #7
0
static int stream_cookie_seeker(void *cookie, __off64_t *position, int whence)
{
    TSRMLS_FETCH();

    *position = php_stream_seek((php_stream *)cookie, (off_t)*position, whence);

    if (*position == -1)
        return -1;
    return 0;
}
Beispiel #8
0
/* {{{ inifile_truncate
 */
static int inifile_truncate(inifile *dba, size_t size)
{
	int res;

	if ((res=php_stream_truncate_set_size(dba->fp, size)) != 0) {
		php_error_docref(NULL, E_WARNING, "Error in ftruncate: %d", res);
		return FAILURE;
	}
	php_stream_seek(dba->fp, size, SEEK_SET);
	return SUCCESS;
}
Beispiel #9
0
/* {{{ inifile_nextkey
 */
int inifile_nextkey(inifile *dba) {
	line_type ln = {{NULL,NULL},{NULL}};

	/*inifile_line_free(&dba->next); ??? */
	php_stream_seek(dba->fp, dba->curr.pos, SEEK_SET);
	ln.key.group = estrdup(dba->curr.key.group ? dba->curr.key.group : "");
	inifile_read(dba, &ln);
	inifile_line_free(&dba->curr);
	dba->curr = ln;
	return ln.key.group || ln.key.name;
}
Beispiel #10
0
static int php_stream_input_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) /* {{{ */
{
	php_stream_input_t *input = stream->abstract;

	if (input->body) {
		int sought = php_stream_seek(input->body, offset, whence);
		*newoffset = (input->body)->position;
		return sought;
	}

	return -1;
}
Beispiel #11
0
PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, zend_off_t readden)
{
	int ret = 1;

	if (php_stream_seek(stream, readden, SEEK_CUR) != 0) {
		ret = 0;
	}
	if (php_stream_mmap_unmap(stream) == 0) {
		ret = 0;
	}

	return ret;
}
Beispiel #12
0
/* Functions for stream handling */
static unsigned long php_cairo_ft_read_func(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) {
	stream_closure *closure;
#ifdef ZTS
	TSRMLS_D;
#endif

	closure = (stream_closure *)stream->descriptor.pointer;
#ifdef ZTS
	TSRMLS_C = closure->TSRMLS_C;
#endif
	php_stream_seek(closure->stream, offset, SEEK_SET);
	return php_stream_read(closure->stream, (char *)buffer, count);
}
Beispiel #13
0
/* {{{ flatfile_nextkey
 */
datum flatfile_nextkey(flatfile *dba) {
	datum res;
	size_t num;
	size_t buf_size = FLATFILE_BLOCK_SIZE;
	char *buf = emalloc(buf_size);

	php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET);
	while(!php_stream_eof(dba->fp)) {
		if (!php_stream_gets(dba->fp, buf, 15)) {
			break;
		}
		num = atoi(buf);
		if (num >= buf_size) {
			buf_size = num + FLATFILE_BLOCK_SIZE;
			buf = erealloc(buf, buf_size);
		}
		num = php_stream_read(dba->fp, buf, num);

		if (!php_stream_gets(dba->fp, buf, 15)) {
			break;
		}
		num = atoi(buf);
		if (num >= buf_size) {
			buf_size = num + FLATFILE_BLOCK_SIZE;
			buf = erealloc(buf, buf_size);
		}
		num = php_stream_read(dba->fp, buf, num);

		if (*(buf)!=0) {
			dba->CurrentFlatFilePos = php_stream_tell(dba->fp);
			res.dptr = buf;
			res.dsize = num;
			return res;
		}
	}
	efree(buf);
	res.dptr = NULL;
	res.dsize = 0;
	return res;
}
Beispiel #14
0
/* {{{ inifile_fetch
 */
val_type inifile_fetch(inifile *dba, const key_type *key, int skip) {
	line_type ln = {{NULL,NULL},{NULL}};
	val_type val;
	int res, grp_eq = 0;

	if (skip == -1 && dba->next.key.group && dba->next.key.name && !inifile_key_cmp(&dba->next.key, key)) {
		/* we got position already from last fetch */
		php_stream_seek(dba->fp, dba->next.pos, SEEK_SET);
		ln.key.group = estrdup(dba->next.key.group);
	} else {
		/* specific instance or not same key -> restart search */
		/* the slow way: restart and seacrch */
		php_stream_rewind(dba->fp);
		inifile_line_free(&dba->next);
	}
	if (skip == -1) {
		skip = 0;
	}
	while(inifile_read(dba, &ln)) {
		if (!(res=inifile_key_cmp(&ln.key, key))) {
			if (!skip) {
				val.value = estrdup(ln.val.value ? ln.val.value : "");
				/* allow faster access by updating key read into next */
				inifile_line_free(&dba->next);
				dba->next = ln;
				dba->next.pos = php_stream_tell(dba->fp);
				return val;
			}
			skip--;
		} else if (res == 1) {
			grp_eq = 1;
		} else if (grp_eq) {
			/* we are leaving group now: that means we cannot find the key */
			break;
		}
	}
	inifile_line_free(&ln);
	dba->next.pos = php_stream_tell(dba->fp);
	return ln.val;
}
Beispiel #15
0
/* {{{ cdb_read */
int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos)
{
    if (php_stream_seek(c->fp, pos, SEEK_SET) == -1) {
        errno = EPROTO;
        return -1;
    }
    while (len > 0) {
        int r;
        do {
            r = php_stream_read(c->fp, buf, len);
        } while ((r == -1) && (errno == EINTR));
        if (r == -1)
            return -1;
        if (r == 0) {
            errno = EPROTO;
            return -1;
        }
        buf += r;
        len -= r;
    }
    return 0;
}
Beispiel #16
0
static inline void _http_send_response_data_fetch(void **buffer, const void *data, size_t data_len, http_send_mode mode, size_t begin, size_t end TSRMLS_DC)
{
	long bsz, got, len = end - begin;
	
	if (!(bsz = HTTP_G->send.buffer_size)) {
		bsz = HTTP_SENDBUF_SIZE;
	}
	
	switch (mode) {
		case SEND_RSRC: {
			php_stream *s = (php_stream *) data;
			if (SUCCESS == php_stream_seek(s, begin, SEEK_SET)) {
				char *buf = emalloc(bsz);
				
				while (len > 0) {
					got = php_stream_read(s, buf, MIN(len, bsz));
					http_send_response_data_plain(buffer, buf, got);
					len -= got;
				}
				
				efree(buf);
			}
			break;
		}
		case SEND_DATA: {
			const char *buf = ((const char *) data) + begin;
			while (len > 0) {
				got = MIN(len, bsz);
				http_send_response_data_plain(buffer, buf, got);
				len -= got;
				buf += got;
			}
			break;
		}
		EMPTY_SWITCH_DEFAULT_CASE();
	}
}
Beispiel #17
0
static PHP_FPOS_T stream_cookie_seeker(void *cookie, zend_off_t position, int whence)
{

	return (PHP_FPOS_T)php_stream_seek((php_stream *)cookie, position, whence);
}
Beispiel #18
0
static int stream_cookie_seeker(void *cookie, zend_off_t position, int whence)
{

	return php_stream_seek((php_stream *)cookie, position, whence);
}
Beispiel #19
0
/* {{{ inifile_delete_replace_append
 */
static int inifile_delete_replace_append(inifile *dba, const key_type *key, const val_type *value, int append, zend_bool *found)
{
	size_t pos_grp_start=0, pos_grp_next;
	inifile *ini_tmp = NULL;
	php_stream *fp_tmp = NULL;
	int ret;

	/* 1) Search group start
	 * 2) Search next group
	 * 3) If not append: Copy group to ini_tmp
	 * 4) Open temp_stream and copy remainder
	 * 5) Truncate stream
	 * 6) If not append AND key.name given: Filtered copy back from ini_tmp
	 *    to stream. Otherwise the user wanted to delete the group.
	 * 7) Append value if given
	 * 8) Append temporary stream
	 */

	assert(!append || (key->name && value)); /* missuse */

	/* 1 - 3 */
	inifile_find_group(dba, key, &pos_grp_start);
	inifile_next_group(dba, key, &pos_grp_next);
	if (append) {
		ret = SUCCESS;
	} else {
		ret = inifile_copy_to(dba, pos_grp_start, pos_grp_next, &ini_tmp);
	}

	/* 4 */
	if (ret == SUCCESS) {
		fp_tmp = php_stream_temp_create(0, 64 * 1024);
		if (!fp_tmp) {
			php_error_docref(NULL, E_WARNING, "Could not create temporary stream");
			ret = FAILURE;
		} else {
			php_stream_seek(dba->fp, 0, SEEK_END);
			if (pos_grp_next != (size_t)php_stream_tell(dba->fp)) {
				php_stream_seek(dba->fp, pos_grp_next, SEEK_SET);
				if (SUCCESS != php_stream_copy_to_stream_ex(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL, NULL)) {
					php_error_docref(NULL, E_WARNING, "Could not copy remainder to temporary stream");
					ret = FAILURE;
				}
			}
		}
	}

	/* 5 */
	if (ret == SUCCESS) {
		if (!value || (key->name && strlen(key->name))) {
			ret = inifile_truncate(dba, append ? pos_grp_next : pos_grp_start); /* writes error on fail */
		}
	}

	if (ret == SUCCESS) {
		if (key->name && strlen(key->name)) {
			/* 6 */
			if (!append && ini_tmp) {
				ret = inifile_filter(dba, ini_tmp, key, found);
			}

			/* 7 */
			/* important: do not query ret==SUCCESS again: inifile_filter might fail but
			 * however next operation must be done.
			 */
			if (value) {
				if (pos_grp_start == pos_grp_next && key->group && strlen(key->group)) {
					php_stream_printf(dba->fp, "[%s]\n", key->group);
				}
				php_stream_printf(dba->fp, "%s=%s\n", key->name, value->value ? value->value : "");
			}
		}

		/* 8 */
		/* important: do not query ret==SUCCESS again: inifile_filter might fail but
		 * however next operation must be done.
		 */
		if (fp_tmp && php_stream_tell(fp_tmp)) {
			php_stream_seek(fp_tmp, 0, SEEK_SET);
			php_stream_seek(dba->fp, 0, SEEK_END);
			if (SUCCESS != php_stream_copy_to_stream_ex(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL, NULL)) {
				zend_throw_error(NULL, "Could not copy from temporary stream - ini file truncated");
				ret = FAILURE;
			}
		}
	}

	if (ini_tmp) {
		php_stream_close(ini_tmp->fp);
		inifile_free(ini_tmp, 0);
	}
	if (fp_tmp) {
		php_stream_close(fp_tmp);
	}
	php_stream_flush(dba->fp);
	php_stream_seek(dba->fp, 0, SEEK_SET);

	return ret;
}
Beispiel #20
0
zend_off_t cdb_file_lseek(php_stream *fp, zend_off_t offset, int whence) {
	php_stream_seek(fp, offset, whence);
	return php_stream_tell(fp);
}
Beispiel #21
0
int cdb_file_lseek(php_stream *fp, off_t offset, int whence TSRMLS_DC) {
	php_stream_seek(fp, offset, whence);
	return php_stream_tell(fp);
}
Beispiel #22
0
static fpos_t stream_cookie_seeker(void *cookie, off_t position, int whence)
{
    TSRMLS_FETCH();
    return (fpos_t)php_stream_seek((php_stream *)cookie, position, whence);
}