现在的位置: 首页 > 综合 > 正文

amfext的一个bug

2014年09月15日 ⁄ 综合 ⁄ 共 4445字 ⁄ 字号 评论关闭

 昨天遇到一个amfext会core的问题,一开始以为是自己的php代码写的有问题,后来仔细看了一下core的地点,结果发现

似乎是amfext的一个bug,它在MAKE_STD_ZVAL之后没有对zval的type进行初始化,而接下来的操作中立即使用了这个

type,如果type=5则调用HASH_OF,一般情况下这句是不会有错的,因为它实际上是从某个数组中取数据出来,并且

这个结果也不会修改(不知道这里为什么要这么写,估计是半成品,为某个目的预留的),因此即使错了也问题不大。

但是在特殊情况下,比如昨天core的情况下,数组的index实在太大了,应该有10亿左右,这个时候可能访问到了某个

保护内在地址,因此才会直接segement fault了。并且在我的机器上运行那段代码是不会core的,只有在同事的机器上会,

并且只要对代码进行任意修改,比如加日志都不会core了,可能就是因为修改了内存加载的地址,导致加载了那个很大的index。

 

附:针对php5.3的patch

-------------------------------------------------------------------------begin------------------------------------------------------

diff -uprN amfext-0.9.2/amf.c amfext/amf.c
--- amfext-0.9.2/amf.c 2008-07-18 18:28:36.000000000 +0800
+++ amfext/amf.c 2011-10-12 12:08:51.000000000 +0800
@@ -844,7 +844,7 @@ static inline void amf_write_zstring(amf
 

   buf->last_chunk->size = 1;  /*  zval chun */

   buf->last_chunk->zv = zstr;

-  ZVAL_ADDREF(zstr);

+  Z_ADDREF_P(zstr);

   buf->chunks++;

   buf->left_in_part -= sizeof(amf_string_chunk);

 

@@ -1185,7 +1185,7 @@ static void amf3_serialize_object(amf_se
   int resultType = AMFC_TYPEDOBJECT;

   int resultValueLength = 0;

   zval** resultValue = struc;

-  int deallocResult = (*struc)->refcount;

+  int deallocResult = Z_REFCOUNT_PP(struc);

 

   resultType = amf_perform_serialize_callback(struc, &className,&classNameLen,&resultValue,var_hash TSRMLS_CC);

   

@@ -2670,7 +2670,7 @@ static int amf3_read_string(zval **rval,
   }

   else

   {

-   newval->refcount--;

+   Z_DELREF_P(newval);

   }

   *rval = newval;

  }

@@ -2772,6 +2772,7 @@ static int amf_read_objectdata(zval **rv
    break;

   }

   MAKE_STD_ZVAL(zValue);

+  zValue->type = 0;

   if(amf_var_unserialize(&zValue,p, max, var_hash TSRMLS_CC) == FAILURE)

   {

    php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf cannot unserialize key <%s>",Z_STRVAL_P(zName));  

@@ -2824,7 +2825,7 @@ static int amf_read_objectdata(zval **rv
  {

   if(zClassname != NULL)

   {

-   ZVAL_ADDREF(zClassname);

+   Z_ADDREF_P(zClassname);

    add_assoc_zval(*rval, "_explicitType",zClassname);

   }

  }

@@ -2906,8 +2907,8 @@ static int amf3_unserialize_var(zval **r
   {

    int iIndex;

    int maxIndex = handle >> 1;

-   HashTable * htOutput = HASH_OF(*rval);

    amf_array_init(*rval, maxIndex TSRMLS_CC);

+   HashTable * htOutput = HASH_OF(*rval);

     /* zval_add_ref(rval) */

    amf_put_in_cache(&(var_hash->objects),*rval);

 

@@ -2927,6 +2928,7 @@ static int amf3_unserialize_var(zval **r
      break;

     }

     MAKE_STD_ZVAL(zValue);

+    zValue->type = 0;

     if(amf3_unserialize_var(&zValue,p,max, var_hash TSRMLS_CC) == FAILURE)

     {

      php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf cannot unserialize key %s",Z_STRVAL_P(zKey));

@@ -2967,6 +2969,7 @@ static int amf3_unserialize_var(zval **r
     {

      zval * zValue;

      MAKE_STD_ZVAL(zValue)

+     zValue->type = 0;

      if(amf3_unserialize_var(&zValue,p,max,var_hash TSRMLS_CC) == FAILURE)

      {

       zval_ptr_dtor(&zValue);

@@ -3045,7 +3048,7 @@ static int amf3_unserialize_var(zval **r
     MAKE_STD_ZVAL(zClassDef);

     amf_array_init(zClassDef,nClassMemberCount+2 TSRMLS_CC);

     add_next_index_long(zClassDef,(bTypedObject?1:0)|nClassMemberCount << AMF_CLASS_MEMBERCOUNT_SHIFT |iDynamicObject|iExternalizable);

-    ZVAL_ADDREF(zClassname);

+    Z_ADDREF_P(zClassname);

     add_next_index_zval(zClassDef, zClassname);

   

      /*  loop over classMemberCoun */

@@ -3056,7 +3059,7 @@ static int amf3_unserialize_var(zval **r
      {

       break;

      }

-     ZVAL_ADDREF(zMemberName);

+     Z_ADDREF_P(zMemberName);

      add_next_index_zval(zClassDef,zMemberName);  /*  pass referenc */

     }

 

@@ -3148,6 +3151,7 @@ static int amf3_unserialize_var(zval **r
       return FAILURE;

      }

      MAKE_STD_ZVAL(zValue)

+     zValue->type = 0;

      if(amf3_unserialize_var(&zValue,p,max, var_hash TSRMLS_CC) == FAILURE)

      {

       zval_ptr_dtor(&zValue);

@@ -3180,6 +3184,7 @@ static int amf3_unserialize_var(zval **r
        break;

       }

       MAKE_STD_ZVAL(zValue)

+      zValue->type = 0;

       if(amf3_unserialize_var(&zValue,p,max, var_hash TSRMLS_CC) == FAILURE)

       {

        zval_ptr_dtor(&zValue);

@@ -3201,7 +3206,7 @@ static int amf3_unserialize_var(zval **r
     {

      if(bTypedObject != 0)

      {

-      ZVAL_ADDREF(zClassname);

+      Z_ADDREF_P(zClassname);

       add_assoc_zval(*rval, "_explicitType",zClassname);

      }

     }

@@ -3300,6 +3305,7 @@ static int amf_var_unserialize(zval **rv
     {

      zval * zValue;

      MAKE_STD_ZVAL(zValue);

+     zValue->type = 0;

      if(amf_var_unserialize(&zValue,p,max, var_hash TSRMLS_CC) == FAILURE)

      {

       php_error_docref(NULL TSRMLS_CC, E_NOTICE, "amf bad unserialized value for array index %d",iIndex);

 

-------------------------------------------------end----------------------------------------

抱歉!评论已关闭.