ModSecurity/apache2/msc_lua.c

108 lines
2.3 KiB
C

#include "msc_lua.h"
#ifdef WITH_LUA
#include "apr_strings.h"
typedef struct {
apr_array_header_t *parts;
apr_pool_t *pool;
} msc_lua_dumpw_t;
typedef struct {
msc_script *script;
int index;
} msc_lua_dumpr_t;
/**
*
*/
static const char* dump_reader(lua_State* L, void* user_data, size_t* size) {
msc_lua_dumpr_t *dumpr = (msc_lua_dumpr_t *)user_data;
/* Do we have more chunks to return? */
if (dumpr->index == dumpr->script->parts->nelts) {
return NULL;
}
/* Get one chunk. */
msc_script_part *part = ((msc_script_part **)dumpr->script->parts->elts)[dumpr->index];
*size = part->len;
dumpr->index++;
return part->data;
}
/**
*
*/
static int dump_writer(lua_State *L, const void* data, size_t len, void* user_data) {
msc_lua_dumpw_t *dump = (msc_lua_dumpw_t *)user_data;
/* Allocate new part, copy the data into it. */
msc_script_part *part = apr_palloc(dump->pool, sizeof(msc_script_part));
part->data = apr_palloc(dump->pool, len);
part->len = len;
memcpy((void *)part->data, data, len);
/* Then add it to the list of parsts. */
*(const msc_script_part **)apr_array_push(dump->parts) = part;
return 0;
}
/**
*
*/
int lua_restore(lua_State *L, msc_script *script) {
msc_lua_dumpr_t dumpr;
dumpr.script = script;
dumpr.index = 0;
return lua_load(L, dump_reader, &dumpr, script->name);
}
/**
*
*/
char *lua_compile(msc_script **script, const char *filename, apr_pool_t *pool) {
lua_State *L = NULL;
msc_lua_dumpw_t dump;
/* Initialise state. */
L = lua_open();
luaL_openlibs(L);
/* Find script. */
if (luaL_loadfile(L, filename)) {
return apr_psprintf(pool, "ModSecurity: Failed to open script %s: %s",
filename, lua_tostring(L, -1));
}
/* Compile script. */
lua_pcall(L, 0, 0, 0);
/* Find the execution entry point. */
lua_getglobal(L, "main");
/* Dump the script into binary form. */
dump.pool = pool;
dump.parts = apr_array_make(pool, 128, sizeof(msc_script_part *));
lua_dump(L, dump_writer, &dump);
(*script) = apr_pcalloc(pool, sizeof(msc_script));
(*script)->name = filename;
(*script)->parts = dump.parts;
/* Destroy state. */
lua_close(L);
return NULL;
}
#endif