示例#1
0
int output(lua_State* lua)
{
    void* luserdata = lua_touserdata(lua, lua_upvalueindex(1));
    if (NULL == luserdata) {
        lua_pushstring(lua, "output() invalid lightuserdata");
        lua_error(lua);
    }
    lua_sandbox* lsb = (lua_sandbox*)luserdata;

    int n = lua_gettop(lua);
    if (n == 0) {
        lua_pushstring(lua, "output() must have at least one argument");
        lua_error(lua);
    }

    int result = 0;
    void* ud = NULL;
    for (int i = 1; result == 0 && i <= n; ++i) {
        switch (lua_type(lua, i)) {
        case LUA_TNUMBER:
            if (dynamic_snprintf(&lsb->m_output, "%0.9g",
                                 lua_tonumber(lua, i))) {
                result = 1;
            }
            break;
        case LUA_TSTRING:
            if (dynamic_snprintf(&lsb->m_output, "%s", lua_tostring(lua, i))) {
                result = 1;
            }
            break;
        case LUA_TNIL:
            if (dynamic_snprintf(&lsb->m_output, "nil")) {
                result = 1;
            }
            break;
        case LUA_TUSERDATA:
            ud = lua_touserdata(lua, i);
            if (heka_circular_buffer == userdata_type(lua, ud, i)) {
                if (output_circular_buffer((circular_buffer*)ud,
                                           &lsb->m_output)) {
                    result = 1;
                }
            }
            break;
        }
    }
    lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT] = lsb->m_output.m_pos;
    if (lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT]
        > lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_MAXIMUM]) {
        lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_MAXIMUM] =
          lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT];
    }
    if (result != 0
        || lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT]
        > lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_LIMIT]) {
        lua_pushstring(lua, "output_limit exceeded");
        lua_error(lua);
    }
    return 0;
}
示例#2
0
int ignore_value_type(lua_sandbox* lsb, serialization_data* data, int index)
{
    void* ud = NULL;
    switch (lua_type(lsb->m_lua, index)) {
    case LUA_TTABLE:
        if (lua_getmetatable(lsb->m_lua, index) != 0) {
            lua_pop(lsb->m_lua, 1); // Remove the metatable.
            return 1;
        }
        if (lua_topointer(lsb->m_lua, index) == data->m_globals) {
            return 1;
        }
        break;
    case LUA_TUSERDATA:
        ud = lua_touserdata(lsb->m_lua, index);
        if ((heka_circular_buffer != userdata_type(lsb->m_lua, ud, index))) {
            return 1;
        }
        break;
    case LUA_TNONE:
    case LUA_TFUNCTION:
    case LUA_TTHREAD:
    case LUA_TLIGHTUSERDATA:
        return 1;
    }
    return 0;
}
示例#3
0
int inject_message(lua_State* lua)
{
    static const char* default_type = "txt";
    static const char* default_name = "";
    void* luserdata = lua_touserdata(lua, lua_upvalueindex(1));
    if (NULL == luserdata) {
        luaL_error(lua, "inject_message() invalid lightuserdata");
    }
    lua_sandbox* lsb = (lua_sandbox*)luserdata;

    void* ud = NULL;
    const char* type = default_type;
    const char* name = default_name;
    switch (lua_gettop(lua)) {
    case 0:
        break;
    case 2:
        name = luaL_checkstring(lua, 2);
        // fallthru
    case 1:
        switch (lua_type(lua, 1)) {
        case LUA_TSTRING:
            type = lua_tostring(lua, 1);
            if (strlen(type) == 0) type = default_type;
            break;
        case LUA_TTABLE:
            type = "";
            if (serialize_table_as_pb(lsb) != 0) {
                luaL_error(lua, "inject_message() cound not encode protobuf - %s",
                           lsb->m_error_message);
            }
            break;
        case LUA_TUSERDATA:
            ud = lua_touserdata(lua, 1);
            if (heka_circular_buffer == userdata_type(lua, ud, 1)) {
                circular_buffer* cb = (circular_buffer*)ud;
                type = get_output_format(cb);
                lsb->m_output.m_pos = 0;
                if (output_circular_buffer(lua, cb, &lsb->m_output)) {
                    luaL_error(lua, lsb->m_error_message);
                }
            } else {
                luaL_typerror(lua, 1, "circular_buffer");
            }
            break;
        default:
            luaL_typerror(lua, 1, "string, table, or circular_buffer");
            break;
        }
        break;
    default:
        luaL_error(lua, "inject_message() takes a maximum of 2 arguments");
        break;
    }

    if (lsb->m_output.m_pos != 0) {
        update_output_stats(lsb);
        if (lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT]
            > lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_LIMIT]) {
            if (lsb->m_error_message[0] == 0) {
                luaL_error(lua, "output_limit exceeded");
            }
            luaL_error(lua, lsb->m_error_message);
        }
        int result = go_lua_inject_message(lsb->m_go,
                                           lsb->m_output.m_data,
                                           (int)(lsb->m_output.m_pos),
                                           (char*)type,
                                           (char*)name);
        lsb->m_output.m_pos = 0;
        if (result != 0) {
            luaL_error(lua, "inject_message() exceeded MaxMsgLoops");
        }
    }
    return 0;
}
示例#4
0
int serialize_kvp(lua_sandbox* lsb, serialization_data* data, size_t parent)
{
    int kindex = -2, vindex = -1;

    if (ignore_value_type(lsb, data, vindex)) return 0;
    int result = serialize_data(lsb, kindex, &lsb->m_output);
    if (result != 0) return result;

    size_t pos = data->m_keys.m_pos;
    if (dynamic_snprintf(&data->m_keys, "%s[%s]", data->m_keys.m_data + parent,
                         lsb->m_output.m_data)) {
        return 1;
    }

    if (lua_type(lsb->m_lua, vindex) == LUA_TTABLE) {
        const void* ptr = lua_topointer(lsb->m_lua, vindex);
        table_ref* seen = find_table_ref(&data->m_tables, ptr);
        if (seen == NULL) {
            seen = add_table_ref(&data->m_tables, ptr, pos);
            if (seen != NULL) {
                data->m_keys.m_pos += 1;
                fprintf(data->m_fh, "%s = {}\n", data->m_keys.m_data + pos);
                result = serialize_table(lsb, data, pos);
            } else {
                snprintf(lsb->m_error_message, ERROR_SIZE,
                         "preserve table out of memory");
                return 1;
            }
        } else {
            fprintf(data->m_fh, "%s = ", data->m_keys.m_data + pos);
            data->m_keys.m_pos = pos;
            fprintf(data->m_fh, "%s\n", data->m_keys.m_data + seen->m_name_pos);
        }
    } else if (lua_type(lsb->m_lua, vindex) == LUA_TUSERDATA) {
        void* ud = lua_touserdata(lsb->m_lua, vindex);
        if (heka_circular_buffer == userdata_type(lsb->m_lua, ud, vindex)) {
            table_ref* seen = find_table_ref(&data->m_tables, ud);
            if (seen == NULL) {
                seen = add_table_ref(&data->m_tables, ud, pos);
                if (seen != NULL) {
                    data->m_keys.m_pos += 1;
                    result = serialize_circular_buffer(
                      data->m_keys.m_data + pos,
                      (circular_buffer*)ud, &lsb->m_output);
                    if (result == 0) {
                        fprintf(data->m_fh, "%s", lsb->m_output.m_data);
                    }
                } else {
                    snprintf(lsb->m_error_message, ERROR_SIZE,
                             "preserve table out of memory");
                    result = 1;
                }
            } else {
                fprintf(data->m_fh, "%s = ", data->m_keys.m_data + pos);
                data->m_keys.m_pos = pos;
                fprintf(data->m_fh, "%s\n", data->m_keys.m_data +
                        seen->m_name_pos);
            }
        }
    } else {
        fprintf(data->m_fh, "%s = ", data->m_keys.m_data + pos);
        data->m_keys.m_pos = pos;
        result = serialize_data(lsb, vindex, &lsb->m_output);
        if (result == 0) {
            fprintf(data->m_fh, "%s\n", lsb->m_output.m_data);
        }
    }
    return result;
}
示例#5
0
int output(lua_State* lua)
{
    void* luserdata = lua_touserdata(lua, lua_upvalueindex(1));
    if (NULL == luserdata) {
        luaL_error(lua, "output() invalid lightuserdata");
    }
    lua_sandbox* lsb = (lua_sandbox*)luserdata;

    int n = lua_gettop(lua);
    if (n == 0) {
        luaL_error(lua, "output() must have at least one argument");
    }

    int result = 0;
    void* ud = NULL;
    for (int i = 1; result == 0 && i <= n; ++i) {
        switch (lua_type(lua, i)) {
        case LUA_TNUMBER:
            if (serialize_double(&lsb->m_output, lua_tonumber(lua, i))) {
                result = 1;
            }
            break;
        case LUA_TSTRING:
            if (dynamic_snprintf(&lsb->m_output, "%s", lua_tostring(lua, i))) {
                result = 1;
            }
            break;
        case LUA_TNIL:
            if (dynamic_snprintf(&lsb->m_output, "nil")) {
                result = 1;
            }
            break;
        case LUA_TBOOLEAN:
            if (dynamic_snprintf(&lsb->m_output, "%s",
                                 lua_toboolean(lsb->m_lua, i)
                                 ? "true" : "false")) {
                result = 1;
            }
            break;
        case LUA_TTABLE:
            if (!dynamic_snprintf(&lsb->m_output, "{")) {
                serialization_data data;
                data.m_globals = NULL;
                data.m_tables.m_size = 64;
                data.m_tables.m_pos = 0;
                data.m_tables.m_array = malloc(data.m_tables.m_size * sizeof(table_ref));
                if (data.m_tables.m_array == NULL) {
                    snprintf(lsb->m_error_message, ERROR_SIZE,
                             "json table serialization out of memory");
                    result = 1;
                } else {
                    lua_checkstack(lsb->m_lua, 2);
                    lua_getfield(lsb->m_lua, i, "_name");
                    if (lua_type(lsb->m_lua, -1) != LUA_TSTRING) {
                        lua_pop(lsb->m_lua, 1); // remove the failed _name result
                        lua_pushstring(lsb->m_lua, "table"); // add default name
                    }
                    lua_pushvalue(lsb->m_lua, i);
                    result = serialize_kvp_as_json(lsb, &data, 1);
                    if (result == 0) {
                        result = dynamic_snprintf(&lsb->m_output, "}\n");
                    }
                    lua_pop(lsb->m_lua, 2); // remove the name and copy of the table
                    free(data.m_tables.m_array);
                }
            } else {
                result = 1;
            }
            break;
        case LUA_TUSERDATA:
            ud = lua_touserdata(lua, i);
            if (heka_circular_buffer == userdata_type(lua, ud, i)) {
                if (output_circular_buffer(lua, (circular_buffer*)ud,
                                           &lsb->m_output)) {
                    result = 1;
                }
            }
            break;
        }
    }
    update_output_stats(lsb);
    if (result != 0
        || lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT]
        > lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_LIMIT]) {
        if (lsb->m_error_message[0] == 0) {
            luaL_error(lua, "output_limit exceeded");
        }
        luaL_error(lua, lsb->m_error_message);
    }
    return 0;
}