示例#1
0
int
lua_amf_decode(lua_State *L)
{
    int          ver;
    int          top;
    size_t       pos;
    size_t       buf_size;
    const char  *buf;
    amf_cursor  *cur;

    ver = luaL_checkint(L, 1);
    check_amf_ver(ver, 1);

    buf = luaL_checklstring(L, 2, &buf_size);

    pos = luaL_optint(L, 3, 0);
    luaL_argcheck(L, pos >= 0, 3,
                  "input offset may not be negative");

    buf_size = min(luaL_optint(L, 4, buf_size), (int)buf_size);
    luaL_argcheck(L, buf_size >= pos, 4, "input buf overflow");

    top = lua_gettop(L);
    cur = amf_cursor_new(buf, buf_size);

    if (ver == AMF_VER0) {
        lua_newtable(L);
        amf0_decode(L, cur, top+1);

    } else {
        lua_newtable(L);
        lua_newtable(L);
        lua_newtable(L);
        amf3_decode(L, cur, top + 1, top + 2, top + 3);

    }

    if (cur->err) {
        lua_pushnil(L);
        lua_pushstring(L, cur->err_msg);

    } else {
        //obj is at top of the stack
        lua_pushnil(L);
    }

    lua_pushinteger(L, buf_size - cur->left);
    amf_cursor_free(cur);

    return 3;
}
示例#2
0
void
amf0_decode(lua_State *L, amf_cursor *c, int ridx)
{
    amf_cursor_need(c, 1);

    switch (c->p[0]) {
    case AMF0_BOOLEAN:
        amf_cursor_need(c, 2);
        lua_pushboolean(L, c->p[1] == 0x01 ? 1 : 0);
        amf_cursor_consume(c, 2);

        break;

    case AMF0_NULL:
    case AMF0_UNDEFINED:
        lua_pushnil(L);
        amf_cursor_consume(c, 1);

        break;

    case AMF0_NUMBER:
        amf_cursor_need(c, 9);
        assert(sizeof(double) == 8);

        double d;
        memcpy(&d, c->p + 1, 8);
        reverse_if_little_endian(&d, 8);
        lua_pushnumber(L, d);
        amf_cursor_consume(c, 9);

        break;

    case AMF0_STRING:
        amf_cursor_consume(c, 1);
        amf0_decode_string(L, c, 16);

        break;

    case AMF0_L_STRING:
        amf_cursor_consume(c, 1);
        amf0_decode_string(L, c, 32);

        break;

    case AMF0_OBJECT:
        amf_cursor_consume(c, 1);
        amf0_decode_to_lua_table(L, c, ridx);
        break;

    case AMF0_ECMA_ARRAY:
        /* the property count, basicly 0 */
        amf_cursor_skip(c, 5);
        amf0_decode_to_lua_table(L, c, ridx);
        break;

    case AMF0_STRICT_ARRAY:
        amf_cursor_need(c, 5);
        uint32_t count = c->p[1] << 24
                         | c->p[2] << 16
                         | c->p[3] << 8
                         | c->p[4];
        amf_cursor_consume(c, 5);

        assert(count <= INT_MAX);
        if (count > INT_MAX) {
            c->err = AMF_CUR_ERR_BADFMT;
            c->err_msg = "strict array elements count overflow";
            return;
        }

        lua_createtable(L, (int)count, 0);
        amf0_decode_remember_ref(L, -1, ridx);

        for (int i = 1; i <= (int)count; i++) {
            amf0_decode(L, c, ridx);
            amf_cursor_checkerr(c);
            lua_rawseti(L, -2, i);
        }
        break;

    case AMF0_TYPED_OBJECT:
        amf_cursor_consume(c, 1);

        amf0_decode_string(L, c, 16);

        amf0_decode_to_lua_table(L, c, ridx);

        /* push alias name */
        lua_pushstring(L, "__amf_alias__");
        lua_pushvalue(L, -3);
        lua_rawset(L, -3);

        /* remove alias from stack */
        lua_remove(L, -2);

        break;

    case AMF0_REFERENCE:
        amf_cursor_need(c, 3);
        uint16_t ref = c->p[1] << 8 | c->p[2];
        amf_cursor_consume(c, 3);

        lua_rawgeti(L, ridx, ref + 1);
        if (lua_isnil(L, -1)) {
            c->err = AMF_CUR_ERR_BADFMT;
            c->err_msg = "reference not found";
            return;
        }

        break;

    case AMF0_AVMPLUS: {
        lua_newtable(L);
        lua_newtable(L);
        int sidx = lua_gettop(L);
        amf3_decode(L, c, sidx, ridx, sidx - 1);
        break;
    }

    default:
        c->err = AMF_CUR_ERR_BADFMT;

    }

}