Пример #1
0
static zend_string* php_password_make_salt(size_t length) /* {{{ */
{
	zend_string *ret, *buffer;

	if (length > (INT_MAX / 3)) {
		php_error_docref(NULL, E_WARNING, "Length is too large to safely generate");
		return NULL;
	}

	buffer = zend_string_alloc(length * 3 / 4 + 1, 0);
	if (FAILURE == php_random_bytes_silent(ZSTR_VAL(buffer), ZSTR_LEN(buffer))) {
		php_error_docref(NULL, E_WARNING, "Unable to generate salt");
		zend_string_release(buffer);
		return NULL;
	}

	ret = zend_string_alloc(length, 0);
	if (php_password_salt_to64(ZSTR_VAL(buffer), ZSTR_LEN(buffer), length, ZSTR_VAL(ret)) == FAILURE) {
		php_error_docref(NULL, E_WARNING, "Generated salt too short");
		zend_string_release(buffer);
		zend_string_release(ret);
		return NULL;
	}
	zend_string_release(buffer);
	ZSTR_VAL(ret)[length] = 0;
	return ret;
}
Пример #2
0
static void php_intl_idn_to_46(INTERNAL_FUNCTION_PARAMETERS,
		const zend_string *domain, uint32_t option, int mode, zval *idna_info)
{
	UErrorCode	  status = U_ZERO_ERROR;
	UIDNA		  *uts46;
	int32_t		  len;
	zend_string	  *buffer;
	UIDNAInfo	  info = UIDNA_INFO_INITIALIZER;

	uts46 = uidna_openUTS46(option, &status);
	if (php_intl_idn_check_status(status, "failed to open UIDNA instance") == FAILURE) {
		RETURN_FALSE;
	}

	if (mode == INTL_IDN_TO_ASCII) {
		const int32_t buffer_capac = 255;
		buffer = zend_string_alloc(buffer_capac, 0);
		len = uidna_nameToASCII_UTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain),
				ZSTR_VAL(buffer), buffer_capac, &info, &status);
		if (len >= buffer_capac || php_intl_idn_check_status(status, "failed to convert name") == FAILURE) {
			uidna_close(uts46);
			zend_string_efree(buffer);
			RETURN_FALSE;
		}
	} else {
		const int32_t buffer_capac = 252*4;
		buffer = zend_string_alloc(buffer_capac, 0);
		len = uidna_nameToUnicodeUTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain),
				ZSTR_VAL(buffer), buffer_capac, &info, &status);
		if (len >= buffer_capac || php_intl_idn_check_status(status, "failed to convert name") == FAILURE) {
			uidna_close(uts46);
			zend_string_efree(buffer);
			RETURN_FALSE;
		}
	}

	ZSTR_VAL(buffer)[len] = '\0';
	ZSTR_LEN(buffer) = len;

	if (info.errors == 0) {
		RETVAL_STR_COPY(buffer);
	} else {
		RETVAL_FALSE;
	}

	if (idna_info) {
		add_assoc_str_ex(idna_info, "result", sizeof("result")-1, zend_string_copy(buffer));
		add_assoc_bool_ex(idna_info, "isTransitionalDifferent",
				sizeof("isTransitionalDifferent")-1, info.isTransitionalDifferent);
		add_assoc_long_ex(idna_info, "errors", sizeof("errors")-1, (zend_long)info.errors);
	}

	zend_string_release(buffer);
	uidna_close(uts46);
}
Пример #3
0
/* {{{ xml_utf8_encode() */
PHPAPI zend_string *xml_utf8_encode(const char *s, size_t len, const XML_Char *encoding)
{
	size_t pos = len;
	zend_string *str;
	unsigned int c;
	unsigned short (*encoder)(unsigned char) = NULL;
	xml_encoding *enc = xml_get_encoding(encoding);

	if (enc) {
		encoder = enc->encoding_function;
	} else {
		/* If the target encoding was unknown, fail */
		return NULL;
	}
	if (encoder == NULL) {
		/* If no encoder function was specified, return the data as-is.
		 */
		str = zend_string_init(s, len, 0);
		return str;
	}
	/* This is the theoretical max (will never get beyond len * 2 as long
	 * as we are converting from single-byte characters, though) */
	str = zend_string_alloc(len * 4, 0);
	str->len = 0;
	while (pos > 0) {
		c = encoder ? encoder((unsigned char)(*s)) : (unsigned short)(*s);
		if (c < 0x80) {
			str->val[str->len++] = (char) c;
		} else if (c < 0x800) {
			str->val[str->len++] = (0xc0 | (c >> 6));
			str->val[str->len++] = (0x80 | (c & 0x3f));
		} else if (c < 0x10000) {
Пример #4
0
ZEND_API void zend_interned_strings_init(void)
{
	char s[2];
	int i;
	zend_string *str;

	zend_init_interned_strings_ht(&interned_strings_permanent, 1);

	zend_new_interned_string = zend_new_interned_string_permanent;
	zend_string_init_interned = zend_string_init_interned_permanent;

	/* interned empty string */
	str = zend_string_alloc(sizeof("")-1, 1);
	ZSTR_VAL(str)[0] = '\000';
	zend_empty_string = zend_new_interned_string_permanent(str);

	s[1] = 0;
	for (i = 0; i < 256; i++) {
		s[0] = i;
		zend_one_char_string[i] = zend_new_interned_string_permanent(zend_string_init(s, 1, 1));
	}

	/* known strings */
	zend_known_strings = pemalloc(sizeof(zend_string*) * ((sizeof(known_strings) / sizeof(known_strings[0]) - 1)), 1);
	for (i = 0; i < (sizeof(known_strings) / sizeof(known_strings[0])) - 1; i++) {
		str = zend_string_init(known_strings[i], strlen(known_strings[i]), 1);
		zend_known_strings[i] = zend_new_interned_string_permanent(str);
	}
}
Пример #5
0
/* {{{ php_escape_shell_arg
 */
PHPAPI zend_string *php_escape_shell_arg(char *str)
{
	int x, y = 0, l = (int)strlen(str);
	zend_string *cmd;
	size_t estimate = (4 * l) + 3;


	cmd = zend_string_alloc(4 * l + 2, 0); /* worst case */

#ifdef PHP_WIN32
	cmd->val[y++] = '"';
#else
	cmd->val[y++] = '\'';
#endif

	for (x = 0; x < l; x++) {
		int mb_len = php_mblen(str + x, (l - x));

		/* skip non-valid multibyte characters */
		if (mb_len < 0) {
			continue;
		} else if (mb_len > 1) {
			memcpy(cmd->val + y, str + x, mb_len);
			y += mb_len;
			x += mb_len - 1;
			continue;
		}

		switch (str[x]) {
#ifdef PHP_WIN32
		case '"':
		case '%':
			cmd->val[y++] = ' ';
			break;
#else
		case '\'':
			cmd->val[y++] = '\'';
			cmd->val[y++] = '\\';
			cmd->val[y++] = '\'';
#endif
			/* fall-through */
		default:
			cmd->val[y++] = str[x];
		}
	}
#ifdef PHP_WIN32
	cmd->val[y++] = '"';
#else
	cmd->val[y++] = '\'';
#endif
	cmd->val[y] = '\0';

	if ((estimate - y) > 4096) {
		/* realloc if the estimate was way overill
		 * Arbitrary cutoff point of 4096 */
		cmd = zend_string_realloc(cmd, y, 0);
	}
	cmd->len = y;
	return cmd;
}
U_CFUNC PHP_FUNCTION(rbbi_get_binary_rules)
{
	BREAKITER_METHOD_INIT_VARS;
	object = getThis();

	if (zend_parse_parameters_none() == FAILURE) {
		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
			"rbbi_get_binary_rules: bad arguments", 0);
		RETURN_FALSE;
	}

	BREAKITER_METHOD_FETCH_OBJECT;

	uint32_t		rules_len;
	const uint8_t	*rules = fetch_rbbi(bio)->getBinaryRules(rules_len);

	if (rules_len > INT_MAX - 1) {
		intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio),
				"rbbi_get_binary_rules: the rules are too large",
				0);
		RETURN_FALSE;
	}

	zend_string *ret_rules = zend_string_alloc(rules_len, 0);
	memcpy(ret_rules->val, rules, rules_len);
	ret_rules->val[rules_len] = '\0';

	RETURN_STR(ret_rules);
}
Пример #7
0
static void co_socket_read(int fd, zend_long length, INTERNAL_FUNCTION_PARAMETERS)
{
    php_swoole_check_reactor();
    if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_SOCKET))
    {
        SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_CO_UTIL | SW_EVENT_READ, co_socket_onReadable);
        SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_CO_UTIL | SW_EVENT_WRITE, co_socket_onWritable);
    }

    if (SwooleG.main_reactor->add(SwooleG.main_reactor, fd, PHP_SWOOLE_FD_CO_UTIL | SW_EVENT_READ) < 0)
    {
        SwooleG.error = errno;
        RETURN_FALSE;
    }

    swConnection *_socket = swReactor_get(SwooleG.main_reactor, fd);
    util_socket *sock = emalloc(sizeof(util_socket));
    bzero(sock, sizeof(util_socket));
    _socket->object = sock;

    sock->fd = fd;
    sock->buf = zend_string_alloc(length + 1, 0);
    sock->nbytes = length <= 0 ? SW_BUFFER_SIZE_STD : length;

    sock->context.state = SW_CORO_CONTEXT_RUNNING;

    coro_save(&sock->context);
    coro_yield();
}
Пример #8
0
/* {{{ php_zlib_encode() */
static zend_string *php_zlib_encode(const char *in_buf, size_t in_len, int encoding, int level)
{
	int status;
	z_stream Z;
	zend_string *out;

	memset(&Z, 0, sizeof(z_stream));
	Z.zalloc = php_zlib_alloc;
	Z.zfree = php_zlib_free;

	if (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, encoding, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) {
		out = zend_string_alloc(PHP_ZLIB_BUFFER_SIZE_GUESS(in_len), 0);

		Z.next_in = (Bytef *) in_buf;
		Z.next_out = (Bytef *) ZSTR_VAL(out);
		Z.avail_in = in_len;
		Z.avail_out = ZSTR_LEN(out);

		status = deflate(&Z, Z_FINISH);
		deflateEnd(&Z);

		if (Z_STREAM_END == status) {
			/* size buffer down to actual length */
			out = zend_string_truncate(out, Z.total_out, 0);
			ZSTR_VAL(out)[ZSTR_LEN(out)] = '\0';
			return out;
		} else {
			zend_string_free(out);
		}
	}

	php_error_docref(NULL, E_WARNING, "%s", zError(status));
	return NULL;
}
Пример #9
0
/* {{{ php_url_encode
 */
PHPAPI zend_string *php_url_encode(char const *s, size_t len)
{
	register unsigned char c;
	unsigned char *to;
	unsigned char const *from, *end;
	zend_string *start;

	from = (unsigned char *)s;
	end = (unsigned char *)s + len;
	start = zend_string_alloc(3 * len, 0);
	to = (unsigned char*)ZSTR_VAL(start);

	while (from < end) {
		c = *from++;

		if (c == ' ') {
			*to++ = '+';
#ifndef CHARSET_EBCDIC
		} else if ((c < '0' && c != '-' && c != '.') ||
				   (c < 'A' && c > '9') ||
				   (c > 'Z' && c < 'a' && c != '_') ||
				   (c > 'z')) {
			to[0] = '%';
			to[1] = hexchars[c >> 4];
			to[2] = hexchars[c & 15];
			to += 3;
#else /*CHARSET_EBCDIC*/
		} else if (!isalnum(c) && strchr("_-.", c) == NULL) {
Пример #10
0
/* {{{ */
static inline zend_string* php_memoize_string(zend_string *string) {
	zend_string *memoized = zend_string_alloc(ZSTR_LEN(string) + sizeof("{}") - 1, 0);

	memcpy(&ZSTR_VAL(memoized)[0], "{", sizeof("{")-1);
	memcpy(&ZSTR_VAL(memoized)[sizeof("{")-1], ZSTR_VAL(string), ZSTR_LEN(string));
	memcpy(&ZSTR_VAL(memoized)[sizeof("{")-1 + ZSTR_LEN(string)], "}", sizeof("}")-1);
	ZSTR_VAL(memoized)[ZSTR_LEN(memoized)]=0;

	return memoized;
} /* }}} */
Пример #11
0
ZEND_API int zend_register_constant(zend_constant *c)
{
	zend_string *lowercase_name = NULL;
	zend_string *name;
	int ret = SUCCESS;

#if 0
	printf("Registering constant for module %d\n", c->module_number);
#endif

    if (c->module_number != PHP_USER_CONSTANT) {
		c->name = zend_new_interned_string(c->name);
	}

	if (!(c->flags & CONST_CS)) {
		lowercase_name = zend_string_alloc(ZSTR_LEN(c->name), c->flags & CONST_PERSISTENT);
		zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ZSTR_VAL(c->name), ZSTR_LEN(c->name));
		lowercase_name = zend_new_interned_string(lowercase_name);
		name = lowercase_name;
	} else {
		char *slash = strrchr(ZSTR_VAL(c->name), '\\');
		if (slash) {
			lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), c->flags & CONST_PERSISTENT);
			zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name));
			lowercase_name = zend_new_interned_string(lowercase_name);
			name = lowercase_name;
		} else {
			name = c->name;
		}
	}

	/* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */
	if ((ZSTR_LEN(c->name) == sizeof("__COMPILER_HALT_OFFSET__")-1
		&& !memcmp(ZSTR_VAL(name), "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1))
		|| zend_hash_add_constant(EG(zend_constants), name, c) == NULL) {

		/* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */
		if (ZSTR_VAL(c->name)[0] == '\0' && ZSTR_LEN(c->name) > sizeof("\0__COMPILER_HALT_OFFSET__")-1
			&& memcmp(ZSTR_VAL(name), "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
		}
		zend_error(E_NOTICE,"Constant %s already defined", ZSTR_VAL(name));
		zend_string_release(c->name);
		if (!(c->flags & CONST_PERSISTENT)) {
			zval_dtor(&c->value);
		}
		ret = FAILURE;
	}
	if (lowercase_name) {
		zend_string_release(lowercase_name);
	}
	return ret;
}
Пример #12
0
ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len)
{
	if (UNEXPECTED(!str->s)) {
		str->a = len < SMART_STR_START_SIZE
				? SMART_STR_START_SIZE
				: SMART_STR_NEW_SIZE(len);
		str->s = zend_string_alloc(str->a, 1);
		ZSTR_LEN(str->s) = 0;
	} else {
		str->a = SMART_STR_NEW_SIZE(len);
		str->s = (zend_string *) realloc(str->s, _ZSTR_HEADER_SIZE + str->a + 1);
	}
}
Пример #13
0
/* {{{ metaphone
 */
static int metaphone(unsigned char *word, size_t word_len, zend_long max_phonemes, zend_string **phoned_word, int traditional)
{
	int w_idx = 0;				/* point in the phonization we're at. */
	int p_idx = 0;				/* end of the phoned phrase */
	size_t max_buffer_len = 0;		/* maximum length of the destination buffer */

/*-- Parameter checks --*/
	/* Negative phoneme length is meaningless */

	if (max_phonemes < 0)
		return -1;

	/* Empty/null string is meaningless */
	/* Overly paranoid */
	/* assert(word != NULL && word[0] != '\0'); */

	if (word == NULL)
		return -1;

/*-- Allocate memory for our phoned_phrase --*/
	if (max_phonemes == 0) {	/* Assume largest possible */
		max_buffer_len = word_len;
		*phoned_word = zend_string_alloc(sizeof(char) * word_len + 1, 0);
	} else {
		max_buffer_len = max_phonemes;
		*phoned_word = zend_string_alloc(sizeof(char) * max_phonemes + 1, 0);
	}


/*-- The first phoneme has to be processed specially. --*/
	/* Find our first letter */
	for (; !isalpha(Curr_Letter); w_idx++) {
		/* On the off chance we were given nothing but crap... */
		if (Curr_Letter == '\0') {
			End_Phoned_Word
				return SUCCESS;	/* For testing */
		}
	}
Пример #14
0
// Creates a buffer of |length| cryptographically secure random bytes. An error
// will be thrown if the bytes could not be generated, for example because the
// PRNG doesn't have enough entropy. Ownership of the created string is passed.
static zend_string* GenerateCryptographicallySecureRandomBytes(size_t length) {
  zend_string* buffer = zend_string_alloc(length, 0);
  if (!buffer) {
    php_error_docref(NULL, E_ERROR, kRandomBytesAllocationError);
    return NULL;
  }

  if (RAND_bytes(buffer->val, length) != 1) {
    php_error_docref(NULL, E_ERROR, kRandomBytesEntropyError);
    zend_string_release(buffer);
    return NULL;
  }

  return buffer;
}
Пример #15
0
static void to_zval_read_sin_addr(const char *data, zval *zv, res_context *ctx)
{
	const struct in_addr *addr = (const struct in_addr *)data;
	socklen_t size = INET_ADDRSTRLEN;
	zend_string *str = zend_string_alloc(size - 1, 0);
	memset(str->val, '\0', size);

	ZVAL_NEW_STR(zv, str);

	if (inet_ntop(AF_INET, addr, Z_STRVAL_P(zv), size) == NULL) {
		do_to_zval_err(ctx, "could not convert IPv4 address to string "
				"(errno %d)", errno);
		return;
	}

	Z_STRLEN_P(zv) = strlen(Z_STRVAL_P(zv));
}
Пример #16
0
static sb4 oci_bind_output_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp) /* {{{ */
{
	struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx;
	pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data;
	zval *parameter;

	if (!param) {
		php_error_docref(NULL, E_WARNING, "param is NULL in oci_bind_output_cb; this should not happen");
		return OCI_ERROR;
	}

	if (Z_ISREF(param->parameter))
        parameter = Z_REFVAL(param->parameter);
    else
        parameter = &param->parameter;

	if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
		P->actual_len = sizeof(OCILobLocator*);
		*bufpp = P->thing;
		*alenpp = &P->actual_len;
		*piecep = OCI_ONE_PIECE;
		*rcodepp = &P->retcode;
		*indpp = &P->indicator;
		return OCI_CONTINUE;
	}

	if (Z_TYPE_P(parameter) == IS_OBJECT || Z_TYPE_P(parameter) == IS_RESOURCE) {
		return OCI_CONTINUE;
	}

	convert_to_string(parameter);
	zval_dtor(parameter);

	Z_STR_P(parameter) = zend_string_alloc(param->max_value_len, 1);
	P->used_for_output = 1;

	P->actual_len = (ub4) Z_STRLEN_P(parameter);
	*alenpp = &P->actual_len;
	*bufpp = (Z_STR_P(parameter))->val;
	*piecep = OCI_ONE_PIECE;
	*rcodepp = &P->retcode;
	*indpp = &P->indicator;

	return OCI_CONTINUE;
} /* }}} */
Пример #17
0
zend_string * ion_buffer_read_all(ion_buffer * buffer) {
    size_t incoming_length = evbuffer_get_length(bufferevent_get_input(buffer));
    zend_string * data;

    if(!incoming_length) {
        return ZSTR_EMPTY_ALLOC();
    }

    data = zend_string_alloc(incoming_length, 0);
    ZSTR_LEN(data) = bufferevent_read(buffer, ZSTR_VAL(data), incoming_length);
    if (ZSTR_LEN(data) > 0) {
        ZSTR_VAL(data)[ZSTR_LEN(data)] = '\0';
        return data;
    } else {
        zend_string_free(data);
        return NULL;
    }
}
Пример #18
0
static zend_string *unserialize_str(const unsigned char **p, size_t len, size_t maxlen)
{
	size_t i, j;
	zend_string *str = zend_string_alloc(len, 0);
	unsigned char *end = *(unsigned char **)p+maxlen;

	if (end < *p) {
		zend_string_free(str);
		return NULL;
	}

	for (i = 0; i < len; i++) {
		if (*p >= end) {
			zend_string_free(str);
			return NULL;
		}
		if (**p != '\\') {
			ZSTR_VAL(str)[i] = (char)**p;
		} else {
			unsigned char ch = 0;

			for (j = 0; j < 2; j++) {
				(*p)++;
				if (**p >= '0' && **p <= '9') {
					ch = (ch << 4) + (**p -'0');
				} else if (**p >= 'a' && **p <= 'f') {
					ch = (ch << 4) + (**p -'a'+10);
				} else if (**p >= 'A' && **p <= 'F') {
					ch = (ch << 4) + (**p -'A'+10);
				} else {
					zend_string_free(str);
					return NULL;
				}
			}
			ZSTR_VAL(str)[i] = (char)ch;
		}
		(*p)++;
	}
	ZSTR_VAL(str)[i] = 0;
	ZSTR_LEN(str) = i;
	return str;
}
Пример #19
0
static void _breakiterator_parts_move_forward(zend_object_iterator *iter)
{
	zoi_break_iter_parts *zoi_bit = (zoi_break_iter_parts*)iter;
	BreakIterator_object *bio = zoi_bit->bio;

	iter->funcs->invalidate_current(iter);

	int32_t cur,
			next;

	cur = bio->biter->current();
	if (cur == BreakIterator::DONE) {
		return;
	}
	next = bio->biter->next();
	if (next == BreakIterator::DONE) {
		return;
	}

	if (zoi_bit->key_type == PARTS_ITERATOR_KEY_LEFT) {
		iter->index = cur;
	} else if (zoi_bit->key_type == PARTS_ITERATOR_KEY_RIGHT) {
		iter->index = next;
	}
	/* else zoi_bit->key_type == PARTS_ITERATOR_KEY_SEQUENTIAL
	 * No need to do anything, the engine increments ->index */

	const char	*s = Z_STRVAL(bio->text);
	size_t		slen = Z_STRLEN(bio->text);
	zend_string	*res;

	if (next == BreakIterator::DONE) {
		next = (int32_t)slen;
	}
	assert(next <= slen && next >= cur);
	res = zend_string_alloc(next - cur, 0);

	memcpy(res->val, &s[cur], res->len);
	res->val[res->len] = '\0';

	ZVAL_STR(&zoi_bit->zoi_cur.current, res);
}
Пример #20
0
static zend_class_entry * spl_find_ce_by_name(zend_string *name, zend_bool autoload)
{
	zend_class_entry *ce;

	if (!autoload) {
		zend_string *lc_name = zend_string_alloc(ZSTR_LEN(name), 0);
		zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name), ZSTR_LEN(name));

		ce = zend_hash_find_ptr(EG(class_table), lc_name);
		zend_string_free(lc_name);
	} else {
 		ce = zend_lookup_class(name);
 	}
 	if (ce == NULL) {
		php_error_docref(NULL, E_WARNING, "Class %s does not exist%s", ZSTR_VAL(name), autoload ? " and could not be loaded" : "");
		return NULL;
	}

	return ce;
}
Пример #21
0
static void php_filter_encode_url(zval *value, const unsigned char* chars, const int char_len, int high, int low, int encode_nul)
{
	unsigned char *p;
	unsigned char tmp[256];
	unsigned char *s = (unsigned char *)chars;
	unsigned char *e = s + char_len;
	zend_string *str;

	memset(tmp, 1, sizeof(tmp)-1);

	while (s < e) {
		tmp[*s++] = '\0';
	}
/* XXX: This is not needed since these chars in the allowed list never include the high/low/null value
	if (encode_nul) {
		tmp[0] = 1;
	}
	if (high) {
		memset(tmp + 127, 1, sizeof(tmp) - 127);
	}
	if (low) {
		memset(tmp, 1, 32);
	}
*/
	str = zend_string_alloc(3 * Z_STRLEN_P(value), 0);
	p = (unsigned char *) ZSTR_VAL(str);
	s = (unsigned char *) Z_STRVAL_P(value);
	e = s + Z_STRLEN_P(value);

	while (s < e) {
		if (tmp[*s]) {
			*p++ = '%';
			*p++ = hexchars[(unsigned char) *s >> 4];
			*p++ = hexchars[(unsigned char) *s & 15];
		} else {
			*p++ = *s;
		}
		s++;
	}
Пример #22
0
/* {{{ */
static inline zend_string* php_memoize_key(const zval *This, const zend_function *function, uint32_t argc, const zval *argv) {
	zend_string *key;
	zend_string *scope = php_memoize_scope(This, function);
	zend_string *name = function->common.function_name;
	zend_string *args = php_memoize_args(argc, argv);

	if (!args) {
		return NULL;
	}

	if (scope == PHP_MEMOIZE_SCOPE_FAILURE) {
		if (args) {
			zend_string_release(args);
		}
		return NULL;
	}

	key = zend_string_alloc(scope ? 
		ZSTR_LEN(scope) + ZSTR_LEN(name) + ZSTR_LEN(args) + sizeof("::") :
		ZSTR_LEN(name) + ZSTR_LEN(args), 0);

	if (scope) {
		memcpy(&ZSTR_VAL(key)[0], ZSTR_VAL(scope), ZSTR_LEN(scope));
		memcpy(&ZSTR_VAL(key)[ZSTR_LEN(scope)], ZSTR_VAL(name), ZSTR_LEN(name));
		memcpy(&ZSTR_VAL(key)[ZSTR_LEN(scope) + ZSTR_LEN(name)], ZSTR_VAL(args), ZSTR_LEN(args));
	} else {
		memcpy(&ZSTR_VAL(key)[0], ZSTR_VAL(name), ZSTR_LEN(name));
		memcpy(&ZSTR_VAL(key)[ZSTR_LEN(name)], ZSTR_VAL(args), ZSTR_LEN(args));
	}
	ZSTR_VAL(key)[ZSTR_LEN(key)] = 0;

	if (scope) {
		zend_string_release(scope);
	}
	zend_string_release(args);
	
	return key;
} /* }}} */
Пример #23
0
static uint32_t add_static_slot(HashTable     *hash,
                                zend_op_array *op_array,
                                uint32_t       op1,
                                uint32_t       op2,
                                uint32_t       kind,
                                int           *cache_size)
{
	uint32_t ret;
	zend_string *key;
	size_t key_len;
	zval *class_name = &op_array->literals[op1];
	zval *prop_name = &op_array->literals[op2];
	zval *pos, tmp;

	key_len = Z_STRLEN_P(class_name) + sizeof("::") - 1 + Z_STRLEN_P(prop_name);
	key = zend_string_alloc(key_len, 0);
	memcpy(ZSTR_VAL(key), Z_STRVAL_P(class_name), Z_STRLEN_P(class_name));
	memcpy(ZSTR_VAL(key) + Z_STRLEN_P(class_name), "::", sizeof("::") - 1);
	memcpy(ZSTR_VAL(key) + Z_STRLEN_P(class_name) + sizeof("::") - 1,
		Z_STRVAL_P(prop_name),
		Z_STRLEN_P(prop_name) + 1);

	ZSTR_H(key) = zend_string_hash_func(key);
	ZSTR_H(key) += kind;

	pos = zend_hash_find(hash, key);
	if (pos) {
		ret = Z_LVAL_P(pos);
	} else {
		ret = *cache_size;
		*cache_size += 2 * sizeof(void *);
		ZVAL_LONG(&tmp, ret);
		zend_hash_add(hash, key, &tmp);
	}
	zend_string_release_ex(key, 0);
	return ret;
}
Пример #24
0
/* {{{ intl_convert_utf16_to_utf8
 * Convert given string from UTF-16 to UTF-8.
 *
 * @param source      String to convert.
 * @param source_len  Length of the source string.
 * @param status      Conversion status.
 *
 * @return zend_string
 */
zend_string* intl_convert_utf16_to_utf8(
	const UChar* src,    int32_t  src_len,
	UErrorCode*  status )
{
	zend_string* dst;
	int32_t      dst_len;

	/* Determine required destination buffer size (pre-flighting). */
	*status = U_ZERO_ERROR;
	u_strToUTF8( NULL, 0, &dst_len, src, src_len, status );

	/* Bail out if an unexpected error occurred.
	 * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough).
	 * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty).
	 */
	if( *status != U_BUFFER_OVERFLOW_ERROR && *status != U_STRING_NOT_TERMINATED_WARNING )
		return NULL;

	/* Allocate memory for the destination buffer (it will be zero-terminated). */
	dst = zend_string_alloc(dst_len, 0);

	/* Convert source string from UTF-8 to UTF-16. */
	*status = U_ZERO_ERROR;
	u_strToUTF8( ZSTR_VAL(dst), dst_len, NULL, src, src_len, status );
	if( U_FAILURE( *status ) )
	{
		zend_string_free(dst);
		return NULL;
	}

	/* U_STRING_NOT_TERMINATED_WARNING is OK for us => reset 'status'. */
	*status = U_ZERO_ERROR;

	ZSTR_VAL(dst)[dst_len] = 0;
	return dst;
}
Пример #25
0
int zend_file_cache_script_store(zend_persistent_script *script, int in_shm)
{
	int fd;
	char *filename;
	zend_file_cache_metainfo info;
#ifdef HAVE_SYS_UIO_H
	struct iovec vec[3];
#endif
	void *mem, *buf;

	filename = zend_file_cache_get_bin_file_path(script->script.filename);

	if (zend_file_cache_mkdir(filename, strlen(ZCG(accel_directives).file_cache)) != SUCCESS) {
		zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot create directory for file '%s'\n", filename);
		efree(filename);
		return FAILURE;
	}

#ifndef ZEND_WIN32
	fd = open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR);
#else
	fd = open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, _S_IREAD | _S_IWRITE);
#endif
	if (fd < 0) {
		if (errno != EEXIST) {
			zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot create file '%s'\n", filename);
		}
		efree(filename);
		return FAILURE;
	}

	if (zend_file_cache_flock(fd, LOCK_EX) != 0) {
		close(fd);
		efree(filename);
		return FAILURE;
	}

#ifdef __SSE2__
	/* Align to 64-byte boundary */
	mem = emalloc(script->size + 64);
	buf = (void*)(((zend_uintptr_t)mem + 63L) & ~63L);
#else
	mem = buf = emalloc(script->size);
#endif

	ZCG(mem) = zend_string_alloc(4096 - (_ZSTR_HEADER_SIZE + 1), 0);

	zend_shared_alloc_init_xlat_table();
	if (!in_shm) {
		script->corrupted = 1; /* used to check if script restored to SHM or process memory */
	}
	zend_file_cache_serialize(script, &info, buf);
	if (!in_shm) {
		script->corrupted = 0;
	}
	zend_shared_alloc_destroy_xlat_table();

	info.checksum = zend_adler32(ADLER32_INIT, buf, script->size);
	info.checksum = zend_adler32(info.checksum, (signed char*)ZSTR_VAL((zend_string*)ZCG(mem)), info.str_size);

#ifdef HAVE_SYS_UIO_H
	vec[0].iov_base = &info;
	vec[0].iov_len = sizeof(info);
	vec[1].iov_base = buf;
	vec[1].iov_len = script->size;
	vec[2].iov_base = ZSTR_VAL((zend_string*)ZCG(mem));
	vec[2].iov_len = info.str_size;

	if (writev(fd, vec, 3) != (ssize_t)(sizeof(info) + script->size + info.str_size)) {
		zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot write to file '%s'\n", filename);
		zend_string_release((zend_string*)ZCG(mem));
		efree(mem);
		unlink(filename);
		efree(filename);
		return FAILURE;
	}
#else
	if (ZEND_LONG_MAX < (zend_long)(sizeof(info) + script->size + info.str_size) ||
		write(fd, &info, sizeof(info)) != sizeof(info) ||
		write(fd, buf, script->size) != script->size ||
		write(fd, ((zend_string*)ZCG(mem))->val, info.str_size) != info.str_size
		) {
		zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot write to file '%s'\n", filename);
		zend_string_release((zend_string*)ZCG(mem));
		efree(mem);
		unlink(filename);
		efree(filename);
		return FAILURE;
	}
#endif

	zend_string_release((zend_string*)ZCG(mem));
	efree(mem);
	if (zend_file_cache_flock(fd, LOCK_UN) != 0) {
		zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename);
	}
	close(fd);
	efree(filename);

	return SUCCESS;
}
Пример #26
0
PHPAPI zend_string *php_quot_print_decode(const unsigned char *str, size_t length, int replace_us_by_ws) /* {{{ */
{
	register size_t i;
	register unsigned const char *p1;
	register unsigned char *p2;
	register unsigned int h_nbl, l_nbl;

	size_t decoded_len, buf_size;
	zend_string *retval;

	static unsigned int hexval_tbl[256] = {
		64, 64, 64, 64, 64, 64, 64, 64, 64, 32, 16, 64, 64, 16, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 64, 64, 64, 64, 64, 64,
		64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
		64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
	};

	if (replace_us_by_ws) {
		replace_us_by_ws = '_';
	}

	i = length, p1 = str; buf_size = length;

	while (i > 1 && *p1 != '\0') {
		if (*p1 == '=') {
			buf_size -= 2;
			p1++;
			i--;
		}
		p1++;
		i--;
	}

	retval = zend_string_alloc(buf_size, 0);
	i = length; p1 = str; p2 = (unsigned char*)ZSTR_VAL(retval);
	decoded_len = 0;

	while (i > 0 && *p1 != '\0') {
		if (*p1 == '=') {
			i--, p1++;
			if (i == 0 || *p1 == '\0') {
				break;
			}
			h_nbl = hexval_tbl[*p1];
			if (h_nbl < 16) {
				/* next char should be a hexadecimal digit */
				if ((--i) == 0 || (l_nbl = hexval_tbl[*(++p1)]) >= 16) {
					efree(retval);
					return NULL;
				}
				*(p2++) = (h_nbl << 4) | l_nbl, decoded_len++;
				i--, p1++;
			} else if (h_nbl < 64) {
				/* soft line break */
				while (h_nbl == 32) {
					if (--i == 0 || (h_nbl = hexval_tbl[*(++p1)]) == 64) {
						efree(retval);
						return NULL;
					}
				}
				if (p1[0] == '\r' && i >= 2 && p1[1] == '\n') {
					i--, p1++;
				}
				i--, p1++;
			} else {
				efree(retval);
				return NULL;
			}
		} else {
			*(p2++) = (replace_us_by_ws == *p1 ? '\x20': *p1);
			i--, p1++, decoded_len++;
		}
	}

	*p2 = '\0';
	ZSTR_LEN(retval) = decoded_len;
	return retval;
}
Пример #27
0
static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
{
	zend_string *digest;
	char *algo, *data;
	size_t algo_len, data_len;
	zend_bool raw_output = raw_output_default;
	const php_hash_ops *ops;
	void *context;
	php_stream *stream = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|b", &algo, &algo_len, &data, &data_len, &raw_output) == FAILURE) {
		return;
	}

	ops = php_hash_fetch_ops(algo, algo_len);
	if (!ops) {
		php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
		RETURN_FALSE;
	}
	if (isfilename) {
		if (CHECK_NULL_PATH(data, data_len)) {
			php_error_docref(NULL, E_WARNING, "Invalid path");
			RETURN_FALSE;
		}
		stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, FG(default_context));
		if (!stream) {
			/* Stream will report errors opening file */
			RETURN_FALSE;
		}
	}

	context = emalloc(ops->context_size);
	ops->hash_init(context);

	if (isfilename) {
		char buf[1024];
		size_t n;

		while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
			ops->hash_update(context, (unsigned char *) buf, n);
		}
		php_stream_close(stream);
	} else {
		ops->hash_update(context, (unsigned char *) data, data_len);
	}

	digest = zend_string_alloc(ops->digest_size, 0);
	ops->hash_final((unsigned char *) ZSTR_VAL(digest), context);
	efree(context);

	if (raw_output) {
		ZSTR_VAL(digest)[ops->digest_size] = 0;
		RETURN_NEW_STR(digest);
	} else {
		zend_string *hex_digest = zend_string_safe_alloc(ops->digest_size, 2, 0, 0);

		php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size);
		ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0;
		zend_string_release(digest);
		RETURN_NEW_STR(hex_digest);
	}
}
Пример #28
0
/* {{{ php_escape_shell_cmd
   Escape all chars that could possibly be used to
   break out of a shell command

   This function emalloc's a string and returns the pointer.
   Remember to efree it when done with it.

   *NOT* safe for binary strings
*/
PHPAPI zend_string *php_escape_shell_cmd(char *str)
{
	register int x, y, l = (int)strlen(str);
	size_t estimate = (2 * l) + 1;
	zend_string *cmd;
#ifndef PHP_WIN32
	char *p = NULL;
#endif


	cmd = zend_string_alloc(2 * l, 0);

	for (x = 0, y = 0; x < l; x++) {
		int mb_len = php_mblen(str + x, (l - x));

		/* skip non-valid multibyte characters */
		if (mb_len < 0) {
			continue;
		} else if (mb_len > 1) {
			memcpy(cmd->val + y, str + x, mb_len);
			y += mb_len;
			x += mb_len - 1;
			continue;
		}

		switch (str[x]) {
#ifndef PHP_WIN32
			case '"':
			case '\'':
				if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) {
					/* noop */
				} else if (p && *p == str[x]) {
					p = NULL;
				} else {
					cmd->val[y++] = '\\';
				}
				cmd->val[y++] = str[x];
				break;
#else
			/* % is Windows specific for environmental variables, ^%PATH% will 
				output PATH while ^%PATH^% will not. escapeshellcmd->val will escape all % and !.
			*/
			case '%':
			case '!':
			case '"':
			case '\'':
#endif
			case '#': /* This is character-set independent */
			case '&':
			case ';':
			case '`':
			case '|':
			case '*':
			case '?':
			case '~':
			case '<':
			case '>':
			case '^':
			case '(':
			case ')':
			case '[':
			case ']':
			case '{':
			case '}':
			case '$':
			case '\\':
			case '\x0A': /* excluding these two */
			case '\xFF':
#ifdef PHP_WIN32
				cmd->val[y++] = '^';
#else
				cmd->val[y++] = '\\';
#endif
				/* fall-through */
			default:
				cmd->val[y++] = str[x];

		}
	}
	cmd->val[y] = '\0';

	if ((estimate - y) > 4096) {
		/* realloc if the estimate was way overill
		 * Arbitrary cutoff point of 4096 */
		cmd = zend_string_truncate(cmd, y, 0);
	}

	cmd->len = y;

	return cmd;
}
Пример #29
0
PHPAPI zend_string *_php_math_number_format_ex(double d, int dec, char *dec_point,
		size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len)
{
	zend_string *res;
	zend_string *tmpbuf;
	char *s, *t;  /* source, target */
	char *dp;
	int integral;
	int reslen = 0;
	int count = 0;
	int is_negative=0;

	if (d < 0) {
		is_negative = 1;
		d = -d;
	}

	dec = MAX(0, dec);
	d = _php_math_round(d, dec, PHP_ROUND_HALF_UP);
	tmpbuf = strpprintf(0, "%.*F", dec, d);
	if (tmpbuf == NULL) {
		return NULL;
	} else if (!isdigit((int)ZSTR_VAL(tmpbuf)[0])) {
		return tmpbuf;
	}

	/* find decimal point, if expected */
	if (dec) {
		dp = strpbrk(ZSTR_VAL(tmpbuf), ".,");
	} else {
		dp = NULL;
	}

	/* calculate the length of the return buffer */
	if (dp) {
		integral = (int)(dp - ZSTR_VAL(tmpbuf));
	} else {
		/* no decimal point was found */
		integral = (int)ZSTR_LEN(tmpbuf);
	}

	/* allow for thousand separators */
	if (thousand_sep) {
		integral += (int)(thousand_sep_len * ((integral-1) / 3));
	}

	reslen = integral;

	if (dec) {
		reslen += dec;

		if (dec_point) {
			reslen += (int)dec_point_len;
		}
	}

	/* add a byte for minus sign */
	if (is_negative) {
		reslen++;
	}
	res = zend_string_alloc(reslen, 0);

	s = ZSTR_VAL(tmpbuf) + ZSTR_LEN(tmpbuf) - 1;
	t = ZSTR_VAL(res) + reslen;
	*t-- = '\0';

	/* copy the decimal places.
	 * Take care, as the sprintf implementation may return less places than
	 * we requested due to internal buffer limitations */
	if (dec) {
		int declen = (int)(dp ? s - dp : 0);
		int topad = dec > declen ? dec - declen : 0;

		/* pad with '0's */
		while (topad--) {
			*t-- = '0';
		}

		if (dp) {
			s -= declen + 1; /* +1 to skip the point */
			t -= declen;

			/* now copy the chars after the point */
			memcpy(t + 1, dp + 1, declen);
		}

		/* add decimal point */
		if (dec_point) {
			t -= dec_point_len;
			memcpy(t + 1, dec_point, dec_point_len);
		}
	}

	/* copy the numbers before the decimal point, adding thousand
	 * separator every three digits */
	while (s >= ZSTR_VAL(tmpbuf)) {
		*t-- = *s--;
		if (thousand_sep && (++count%3)==0 && s >= ZSTR_VAL(tmpbuf)) {
			t -= thousand_sep_len;
			memcpy(t + 1, thousand_sep, thousand_sep_len);
		}
	}

	/* and a minus sign, if needed */
	if (is_negative) {
		*t-- = '-';
	}

	ZSTR_LEN(res) = reslen;
	zend_string_release(tmpbuf);
	return res;
}
Пример #30
0
// Translates |input| of |input_len| using aes-gcm-128. The |input| will either
// be encrypted or decrypted based on |direction|. The |key|, which must be of
// size |kAesGcmKeyBytes|, and the |nonce|, which must be of size
// |kAesGcmNonceBytes|, will be used for the translation. A new zend string will
// be returned on success, or NULL (with a visible warning) on failure.
static zend_string* AesGcm128Translate(
    int direction, char* input, size_t input_len, char* key, char* nonce) {
  const EVP_CIPHER* aead = EVP_aes_128_gcm();

  zend_string* result = NULL;

  int expected_len = 0;
  int result_len = 0;

  EVP_CIPHER_CTX context;
  EVP_CIPHER_CTX_init(&context);

  do {
    if (direction == TRANSLATE_ENCRYPT) {
      if (EVP_EncryptInit_ex(&context, aead, 0, 0, 0) != 1) {
        php_error_docref(NULL, E_ERROR, kTranslateInitGcmError);
        break;
      }

      if (EVP_CIPHER_CTX_ctrl(&context, EVP_CTRL_GCM_SET_IVLEN, 12, 0) != 1 ||
          EVP_EncryptInit_ex(&context, 0, 0, key, nonce) != 1) {
        php_error_docref(NULL, E_ERROR, kTranslateKeyNonceError);
        break;
      }

      expected_len = input_len + 16 /* authentication tag */;
      result = zend_string_alloc(expected_len, 0);
      if (!result) {
        php_error_docref(NULL, E_ERROR, kTranslateAllocationError);
        break;
      }

      if (EVP_EncryptUpdate(&context, result->val, &result_len, input, input_len) != 1 ||
          EVP_EncryptFinal_ex(&context, result->val, &result_len) != 1) {
        php_error_docref(NULL, E_ERROR, kTranslateEncryptInputError);
        zend_string_release(result);
        result = NULL;
        break;
      }

      if (EVP_CIPHER_CTX_ctrl(&context, EVP_CTRL_GCM_GET_TAG, 16, result->val + input_len) != 1) {
        php_error_docref(NULL, E_ERROR, kTranslateEncryptAuthError);
        zend_string_release(result);
        result = NULL;
        break;
      }

      // Encryption successful!

    } else {
      if (EVP_DecryptInit_ex(&context, aead, 0, 0, 0) != 1) {
        php_error_docref(NULL, E_ERROR, kTranslateInitGcmError);
        break;
      }

      expected_len = input_len - 16;

      if (EVP_CIPHER_CTX_ctrl(&context, EVP_CTRL_GCM_SET_TAG, 16, input + expected_len) != 1) {
        php_error_docref(NULL, E_ERROR, kTranslateDecryptAuthError);
        break;
      }

      if (EVP_CIPHER_CTX_ctrl(&context, EVP_CTRL_GCM_SET_IVLEN, 12, 0) != 1 ||
          EVP_DecryptInit_ex(&context, 0, 0, key, nonce) != 1) {
        php_error_docref(NULL, E_ERROR, kTranslateKeyNonceError);
        break;
      }

      result = zend_string_alloc(expected_len, 0);
      if (!result) {
        php_error_docref(NULL, E_ERROR, kTranslateAllocationError);
        break;
      }

      if (EVP_DecryptUpdate(&context, result->val, &result_len, input, expected_len) != 1 ||
          EVP_DecryptFinal_ex(&context, result->val + expected_len, &result_len) != 1) {
        php_error_docref(NULL, E_WARNING, kTranslateDecryptionWarning);

        zend_string_release(result);
        result = NULL;
        break;
      }

      // Decryption successful!
    }
  } while(0);

  EVP_CIPHER_CTX_cleanup(&context);

  return result;
}