I'm making slow progress on an updated version of AMFEXT. Most of the encoding functionality is complete but I'm struggling a bit with the decoding functions because I need to return zvals and other objects. In particular, I'm getting some memory leak notifications and I'm also getting some weird behavior when I add values to a HashTable and retrieve them later. I'd very much appreciate some guidance. A code review would be awesome if anyone is willing.
I've posted the extension's source on github at https://github.com/sneakyimp/amfext === Problem 1: I pass a *zval to one of my functions by reference and it gets pointed to a zval object representing a string. I was trying to check Z_TYPE_P(myzval)==IS_STRING and even though it is a string with a type value of 6, the check says otherwise, though. I'm baffled by this because my code looks just like examples I've seen in 'Extending and Embedding PHP.' Code: zval *assoc_key; MAKE_STD_ZVAL(assoc_key); amf_read_string(buf, buf_len, buf_cursor, assoc_key, flags, htComplexObjects, htObjectTypeTraits, htStrings TSRMLS_CC); // had to remove this check because it was failing on empty strings for some reason if (Z_TYPE_P(assoc_key) == IS_STRING) { // the baffling thing is it returns "String expected, but returned object type is 6" php_error_docref(NULL TSRMLS_CC, E_ERROR, "String expected, but returned object type is %d", (unsigned int)Z_TYPE_P(assoc_key)); } Here's a link to the source on github: https://github.com/sneakyimp/amfext/blob/master/amf.c#L1242 === Problem 2: Similar to the previous problem, but the issue is that string zval is retrieved from a HashTable and when it comes out, the type value is messed up value. Code: // make sure it's a string // WTF? Z_TYPE_P(strz) is never IS_STRING and Z_STRVAL_P returns messed up values // e.g., "ZVAL stored at index 0 is not a string, type=-30420640" if (Z_TYPE_P(strz) != IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "ZVAL stored at index %d is not a string, type=%d\n", (unsigned int)str_index, Z_STRVAL_P(strz)); } Here's a link to the source on github: https://github.com/sneakyimp/amfext/blob/master/amf.c#L1300 === Problem 3: Memory leaks! I concocted this test PHP script for my amf_decode function. It retrieves a data file containing an amf3-serialized array: array("abc", "abc", "abc", "a" => 1, "b" => 2, "c" => 3) And then decodes it. The PHP script: <?php $dir = dirname(__FILE__); $str = file_get_contents($dir . "/amf_arr_abc123.dat"); var_dump(amf_decode($str)); The output of the script: array(6) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) [0]=> string(3) "abc" [1]=> string(3) "abc" [2]=> string(3) "abc" } [Fri Oct 2 12:00:21 2015] Script: '/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php' /home/jaith/src/php-5.5.29/ext/amf/amf.c(1324) : Freeing 0x7F30D2091080 (32 bytes), script=/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php Last leak repeated 3 times [Fri Oct 2 12:00:21 2015] Script: '/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php' /home/jaith/src/php-5.5.29/ext/amf/amf.c(1330) : Freeing 0x7F30D2091270 (2 bytes), script=/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php Last leak repeated 2 times [Fri Oct 2 12:00:21 2015] Script: '/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php' /home/jaith/src/php-5.5.29/ext/amf/amf.c(1325) : Freeing 0x7F30D20914F0 (2 bytes), script=/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php Last leak repeated 3 times [Fri Oct 2 12:00:21 2015] Script: '/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php' /home/jaith/src/php-5.5.29/ext/amf/amf.c(1238) : Freeing 0x7F30D2092348 (32 bytes), script=/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php [Fri Oct 2 12:00:21 2015] Script: '/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php' /home/jaith/src/php-5.5.29/ext/amf/amf.c(1333) : Freeing 0x7F30D2092AB8 (1 bytes), script=/home/jaith/src/php-5.5.29/ext/amf/jta/read_arr_test2.php === Total 13 memory leaks detected ===