summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2014-04-23 19:05:16 +0200
committerNikita Popov <nikic@php.net>2014-04-23 19:34:51 +0200
commit08ae88157b4f73154b2f1ffe72c3957edb3772fc (patch)
treeb4c1ae6e553379588d5b214d01297d476de3e4a7 /Zend
parent20580a511c029582fd2be6c8efbed40c89f7a874 (diff)
downloadphp-git-08ae88157b4f73154b2f1ffe72c3957edb3772fc.tar.gz
Allocate zend_strings with correct size
For me (32bit) sizeof(zend_string) is 20, which means that the char[1] array at the end is padded with three bytes. Thus allocating based on sizeof(zend_string)-1 overallocates by those 3 padding bytes. This commit fixes the allocation size, by using XtOffsetOf.
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend.h30
-rw-r--r--Zend/zend_ini.h30
-rw-r--r--Zend/zend_string.h10
3 files changed, 36 insertions, 34 deletions
diff --git a/Zend/zend.h b/Zend/zend.h
index 3aae759dde..799eb25cfe 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -347,6 +347,36 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore
# define UNEXPECTED(condition) (condition)
#endif
+#ifndef XtOffsetOf
+# if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX))
+# ifdef __STDC__
+# define XtOffset(p_type, field) _Offsetof(p_type, field)
+# else
+# ifdef CRAY2
+# define XtOffset(p_type, field) \
+ (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
+
+# else /* !CRAY2 */
+
+# define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))
+
+# endif /* !CRAY2 */
+# endif /* __STDC__ */
+# else /* ! (CRAY || __arm) */
+
+# define XtOffset(p_type, field) \
+ ((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
+
+# endif /* !CRAY */
+
+# ifdef offsetof
+# define XtOffsetOf(s_type, field) offsetof(s_type, field)
+# else
+# define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
+# endif
+
+#endif
+
#include "zend_string.h"
static zend_always_inline zend_uint zval_refcount_p(zval* pz) {
diff --git a/Zend/zend_ini.h b/Zend/zend_ini.h
index 8782ec6f20..0a0c1137e1 100644
--- a/Zend/zend_ini.h
+++ b/Zend/zend_ini.h
@@ -27,36 +27,6 @@
#define ZEND_INI_ALL (ZEND_INI_USER|ZEND_INI_PERDIR|ZEND_INI_SYSTEM)
-#ifndef XtOffsetOf
-# if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX))
-# ifdef __STDC__
-# define XtOffset(p_type, field) _Offsetof(p_type, field)
-# else
-# ifdef CRAY2
-# define XtOffset(p_type, field) \
- (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
-
-# else /* !CRAY2 */
-
-# define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))
-
-# endif /* !CRAY2 */
-# endif /* __STDC__ */
-# else /* ! (CRAY || __arm) */
-
-# define XtOffset(p_type, field) \
- ((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
-
-# endif /* !CRAY */
-
-# ifdef offsetof
-# define XtOffsetOf(s_type, field) offsetof(s_type, field)
-# else
-# define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
-# endif
-
-#endif
-
#define ZEND_INI_MH(name) int name(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC)
#define ZEND_INI_DISP(name) void name(zend_ini_entry *ini_entry, int type)
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
index 5226c06e79..af83d4d3b5 100644
--- a/Zend/zend_string.h
+++ b/Zend/zend_string.h
@@ -54,6 +54,8 @@ END_EXTERN_C()
#define STR_RELEASE(s) zend_str_release(s)
#define STR_EMPTY_ALLOC() CG(empty_string)
+#define _STR_HEADER_SIZE XtOffsetOf(zend_string, val)
+
static zend_always_inline zend_ulong zend_str_hash_val(zend_string *s)
{
if (!s->h) {
@@ -93,7 +95,7 @@ static zend_always_inline zend_uint zend_str_delref(zend_string *s)
static zend_always_inline zend_string *zend_str_alloc(int len, int persistent)
{
- zend_string *ret = pemalloc(sizeof(zend_string) + len, persistent);
+ zend_string *ret = pemalloc(_STR_HEADER_SIZE + len + 1, persistent);
GC_REFCOUNT(ret) = 1;
#if 1
@@ -111,7 +113,7 @@ static zend_always_inline zend_string *zend_str_alloc(int len, int persistent)
static zend_always_inline zend_string *zend_str_safe_alloc(size_t n, size_t m, size_t l, int persistent)
{
- zend_string *ret = safe_pemalloc(n, m, sizeof(zend_string) + l - 1, persistent);
+ zend_string *ret = safe_pemalloc(n, m, _STR_HEADER_SIZE + l + 1, persistent);
GC_REFCOUNT(ret) = 1;
#if 1
@@ -161,7 +163,7 @@ static zend_always_inline zend_string *zend_str_realloc(zend_string *s, int len,
ret = STR_ALLOC(len, persistent);
memcpy(ret->val, s->val, (len > s->len ? s->len : len) + 1);
} else if (STR_REFCOUNT(s) == 1) {
- ret = perealloc(s, sizeof(zend_string) + len, persistent);
+ ret = perealloc(s, _STR_HEADER_SIZE + len + 1, persistent);
ret->len = len;
STR_FORGET_HASH_VAL(ret);
} else {
@@ -180,7 +182,7 @@ static zend_always_inline zend_string *zend_str_safe_realloc(zend_string *s, siz
ret = STR_SAFE_ALLOC(n, m, l, persistent);
memcpy(ret->val, s->val, ((n * m) + l > s->len ? s->len : ((n * m) + l)) + 1);
} else if (STR_REFCOUNT(s) == 1) {
- ret = safe_perealloc(s, n, m, sizeof(zend_string) + l - 1, persistent);
+ ret = safe_perealloc(s, n, m, _STR_HEADER_SIZE + l + 1, persistent);
ret->len = (n * m) + l;
STR_FORGET_HASH_VAL(ret);
} else {