# good example of unserialization fundamentals?

- Thread: https://externals.io/message/88584
- Original archive: https://news-web.php.net/php.internals/88584
- Started by j adams on 2015-09-30T20:39:26+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #88584 — j adams — 2015-09-30T20:39:26+00:00

URL: https://externals.io/message/88584#88584

I have completed a first draft of serialization functionality which is
intended to be an updated to amfext. It's on github[0] if anyone is
interested. I would now like to write all the unserialization routines and
would like some suggestions from experienced php devs. I've been reading
Sara Golemon's book, but am still a little unsure.

In particular, I want my userland function, amf_decode to accept as a
parameter a string (and possibly other args). This is not so difficult but
I must call upon another function, php_amf_decode, which needs to be able
to handle recursive calls.

Something like this:

// userland function
static PHP_FUNCTION(amf_decode) {
    char *buf; // char buffer, contains serialize data string
    int buf_len, buf_cursor=0; // the length of the buffer
    long flags = 0;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &buf,
&buf_len, &flags) == FAILURE) {
        return;
    }

    if (!buf_len) {
        RETURN_NULL();
    }

    php_amf_decode(return_value, buf, buf_len, &buf_cursor, flags
TSRMLS_CC);
}

// proposed recursive decoding function
PHP_AMF_API void php_amf_decode(zval *return_value, char *buf, int buf_len,
int *buf_cursor, long flags TSRMLS_DC)
{

    // is it safe to use these macros in this recursive function?
    RETVAL_BOOL(1);

    // or this
    RETURN_LONG(42);


}


[0] https://github.com/sneakyimp/amfext

---

## #88585 — Sean DuBois — 2015-09-30T20:58:57+00:00

URL: https://externals.io/message/88584#88585 · In reply to: #88584

> I have completed a first draft of serialization functionality which is
> intended to be an updated to amfext. It's on github[0] if anyone is
> interested. I would now like to write all the unserialization routines and
> would like some suggestions from experienced php devs. I've been reading
> Sara Golemon's book, but am still a little unsure.
>
> In particular, I want my userland function, amf_decode to accept as a
> parameter a string (and possibly other args). This is not so difficult but
> I must call upon another function, php_amf_decode, which needs to be able
> to handle recursive calls.
>
> Something like this:
>
> // userland function
> static PHP_FUNCTION(amf_decode) {
>     char *buf; // char buffer, contains serialize data string
>     int buf_len, buf_cursor=0; // the length of the buffer
>     long flags = 0;
>
>     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &buf,
> &buf_len, &flags) == FAILURE) {
>         return;
>     }
>
>     if (!buf_len) {
>         RETURN_NULL();
>     }
>
>     php_amf_decode(return_value, buf, buf_len, &buf_cursor, flags
> TSRMLS_CC);
> }
>
> // proposed recursive decoding function
> PHP_AMF_API void php_amf_decode(zval *return_value, char *buf, int buf_len,
> int *buf_cursor, long flags TSRMLS_DC)
> {
>
>     // is it safe to use these macros in this recursive function?
>     RETVAL_BOOL(1);
>
>     // or this
>     RETURN_LONG(42);
>
>
> }
>
>
> [0] https://github.com/sneakyimp/amfext

Yep those are safe!

RETVAL_* expands out so you don't have to repeat the variable `return_value`
    ZVAL_LONG(return_value, l)

RETURN_* expands out so you don't have to call return OR specify the variable `return_value`
   ZVAL_LONG(return_value, l)
   return;

Here they are in 5.6 http://lxr.php.net/xref/PHP_5_6/Zend/zend_API.h#618
---

A great tool to look these things up quickly is lxr, sure beats grep!
http://lxr.php.net/search?q=&defs=RETURN_LONG&refs=&path=&hist=&project=PHP_5_6

---

## #88587 — j adams — 2015-09-30T21:11:59+00:00

URL: https://externals.io/message/88584#88587 · In reply to: #88585

Thanks for your response. I do follow the concept of macros (and my IDE
expands them for me if I need), however, I just want to confirm that it's
OK to be using these in a *recursive function*? I'm aware from S. Golemon's
book that these (deeply nested) macros also have the effect of incrementing
refcounts and such. For instance, I'm sure the RETURN_* macros will break
your code if you don't have a zval *return_value defined in the current
scope. Are there other caveats or heuristic rules to avoid abusing these
macros?

OH, and perhaps I forgot to ask with my original post. Can anyone point me
to a good example of a function that takes some userland input and
recursively interprets it as possibly nested arrays or objects? I've been
looking at php_json_decode_ex[0] but it is allocating and freeing memory
for utf16/8 converters and JSON_Parser_structs and so on.


[0] http://lxr.php.net/xref/PHP_5_6/ext/json/json.c#683



> 
> > […]
> and
> > […]
> but
> > […]
> buf_len,
> > […]
>
> Yep those are safe!
>
> RETVAL_* expands out so you don't have to repeat the variable
> `return_value`
>     ZVAL_LONG(return_value, l)
>
> RETURN_* expands out so you don't have to call return OR specify the
> variable `return_value`
>    ZVAL_LONG(return_value, l)
>    return;
>
> Here they are in 5.6 http://lxr.php.net/xref/PHP_5_6/Zend/zend_API.h#618
> ---
>
> A great tool to look these things up quickly is lxr, sure beats grep!
>
> http://lxr.php.net/search?q=&defs=RETURN_LONG&refs=&path=&hist=&project=PHP_5_6
