Quellcode durchsuchen

[Minor] Move rspamd_text to a sepatate unit

tags/1.9.3
Vsevolod Stakhov vor 5 Jahren
Ursprung
Commit
fa7dcbab1f
4 geänderte Dateien mit 423 neuen und 322 gelöschten Zeilen
  1. 4
    2
      doc/Makefile
  2. 2
    1
      src/lua/CMakeLists.txt
  3. 0
    319
      src/lua/lua_task.c
  4. 417
    0
      src/lua/lua_text.c

+ 4
- 2
doc/Makefile Datei anzeigen

@@ -21,7 +21,7 @@ lua-dirs:
lua-doc: lua-dirs rspamd_regexp rspamd_ip rspamd_config rspamd_task ucl rspamd_http rspamd_trie \
rspamd_resolver rspamd_redis rspamd_upstream_list rspamd_expression rspamd_mimepart rspamd_logger rspamd_url \
rspamd_tcp rspamd_mempool rspamd_html rspamd_util rspamd_fann rspamd_sqlite3 rspamd_cryptobox rspamd_map \
lua_redis lua_util lua_maps lua_clickhouse lua_selectors rspamd_udp
lua_redis lua_util lua_maps lua_clickhouse lua_selectors rspamd_udp rspamd_text

lua_redis:
$(LLUADOC) < ../lualib/lua_redis.lua > markdown/lua/lua_redis.md
@@ -83,4 +83,6 @@ rspamd_cryptobox: ../src/lua/lua_cryptobox.c
rspamd_map: ../src/lua/lua_map.c
$(LUADOC) < ../src/lua/lua_map.c > markdown/lua/rspamd_map.md
rspamd_udp: ../src/lua/lua_udp.c
$(LUADOC) < ../src/lua/lua_udp.c > markdown/lua/rspamd_udp.md
$(LUADOC) < ../src/lua/lua_udp.c > markdown/lua/rspamd_udp.md
rspamd_text: ../src/lua/lua_text.c
$(LUADOC) < ../src/lua/lua_text.c > markdown/lua/rspamd_text.md

+ 2
- 1
src/lua/CMakeLists.txt Datei anzeigen

@@ -28,6 +28,7 @@ SET(LUASRC ${CMAKE_CURRENT_SOURCE_DIR}/lua_common.c
${CMAKE_CURRENT_SOURCE_DIR}/lua_map.c
${CMAKE_CURRENT_SOURCE_DIR}/lua_thread_pool.c
${CMAKE_CURRENT_SOURCE_DIR}/lua_dns.c
${CMAKE_CURRENT_SOURCE_DIR}/lua_udp.c)
${CMAKE_CURRENT_SOURCE_DIR}/lua_udp.c
${CMAKE_CURRENT_SOURCE_DIR}/lua_text.c)

SET(RSPAMD_LUA ${LUASRC} PARENT_SCOPE)

+ 0
- 319
src/lua/lua_task.c Datei anzeigen

@@ -1185,35 +1185,6 @@ static const struct luaL_reg archivelib_m[] = {
{NULL, NULL}
};

/* Blob methods */
LUA_FUNCTION_DEF (text, fromstring);
LUA_FUNCTION_DEF (text, fromtable);
LUA_FUNCTION_DEF (text, len);
LUA_FUNCTION_DEF (text, str);
LUA_FUNCTION_DEF (text, ptr);
LUA_FUNCTION_DEF (text, save_in_file);
LUA_FUNCTION_DEF (text, take_ownership);
LUA_FUNCTION_DEF (text, gc);

static const struct luaL_reg textlib_f[] = {
LUA_INTERFACE_DEF (text, fromstring),
LUA_INTERFACE_DEF (text, fromtable),
{NULL, NULL}
};

static const struct luaL_reg textlib_m[] = {
LUA_INTERFACE_DEF (text, len),
LUA_INTERFACE_DEF (text, str),
LUA_INTERFACE_DEF (text, ptr),
LUA_INTERFACE_DEF (text, take_ownership),
LUA_INTERFACE_DEF (text, save_in_file),
{"write", lua_text_save_in_file},
{"__len", lua_text_len},
{"__tostring", lua_text_str},
{"__gc", lua_text_gc},
{NULL, NULL}
};

/* Utility functions */
struct rspamd_task *
lua_check_task (lua_State * L, gint pos)
@@ -5978,277 +5949,6 @@ lua_archive_get_filename (lua_State *L)
return 1;
}

/* Text methods */
static gint
lua_text_fromstring (lua_State *L)
{
LUA_TRACE_POINT;
const gchar *str;
gsize l = 0;
struct rspamd_lua_text *t;

str = luaL_checklstring (L, 1, &l);

if (str) {
t = lua_newuserdata (L, sizeof (*t));
t->start = g_malloc (l + 1);
rspamd_strlcpy ((char *)t->start, str, l + 1);
t->len = l;
t->flags = RSPAMD_TEXT_FLAG_OWN;
rspamd_lua_setclass (L, "rspamd{text}", -1);
}
else {
return luaL_error (L, "invalid arguments");
}


return 1;
}

static gint
lua_text_fromtable (lua_State *L)
{
LUA_TRACE_POINT;
const gchar *delim = "", *st;
struct rspamd_lua_text *t, *elt;
gsize textlen = 0, dlen, stlen, tblen;
gchar *dest;

if (!lua_istable (L, 1)) {
return luaL_error (L, "invalid arguments");
}

if (lua_type (L, 2) == LUA_TSTRING) {
delim = lua_tolstring (L, 2, &dlen);
}
else {
dlen = strlen (delim);
}

/* Calculate length needed */
tblen = rspamd_lua_table_size (L, 1);

for (guint i = 0; i < tblen; i ++) {
lua_rawgeti (L, 1, i + 1);

if (lua_type (L, -1) == LUA_TSTRING) {
#if LUA_VERSION_NUM >= 502
stlen = lua_rawlen (L, -1);
#else
stlen = lua_objlen (L, -1);
#endif
textlen += stlen;
}
else {
elt = lua_check_text (L, -1);

if (elt) {
textlen += elt->len;
}
}

lua_pop (L, 1);
textlen += dlen;
}

/* Allocate new text */
t = lua_newuserdata (L, sizeof (*t));
dest = g_malloc (textlen);
t->start = dest;
t->len = textlen;
t->flags = RSPAMD_TEXT_FLAG_OWN;
rspamd_lua_setclass (L, "rspamd{text}", -1);

for (guint i = 0; i < tblen; i ++) {
lua_rawgeti (L, 1, i + 1);

if (lua_type (L, -1) == LUA_TSTRING) {
st = lua_tolstring (L, -1, &stlen);
memcpy (dest, st, stlen);
dest += stlen;
}
else {
elt = lua_check_text (L, -1);

if (elt) {
memcpy (dest, elt->start, elt->len);
}
}

memcpy (dest, delim, dlen);
lua_pop (L, 1);
}

return 1;
}

static gint
lua_text_len (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);
gsize l = 0;

if (t != NULL) {
l = t->len;
}
else {
return luaL_error (L, "invalid arguments");
}

lua_pushinteger (L, l);

return 1;
}

static gint
lua_text_str (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);

if (t != NULL) {
lua_pushlstring (L, t->start, t->len);
}
else {
return luaL_error (L, "invalid arguments");
}

return 1;
}

static gint
lua_text_ptr (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);

if (t != NULL) {
lua_pushlightuserdata (L, (gpointer)t->start);
}
else {
return luaL_error (L, "invalid arguments");
}

return 1;
}

static gint
lua_text_take_ownership (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);
gchar *dest;

if (t != NULL) {
if (t->flags & RSPAMD_TEXT_FLAG_OWN) {
/* We already own it */
lua_pushboolean (L, true);
}
else {
dest = g_malloc (t->len);
memcpy (dest, t->start, t->len);
t->start = dest;
t->flags |= RSPAMD_TEXT_FLAG_OWN;
lua_pushboolean (L, true);
}
}
else {
return luaL_error (L, "invalid arguments");
}

return 1;
}

static gint
lua_text_save_in_file (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);
const gchar *fname = NULL;
guint mode = 00644;
gint fd = -1;
gboolean need_close = FALSE;

if (t != NULL) {
if (lua_type (L, 2) == LUA_TSTRING) {
fname = luaL_checkstring (L, 2);

if (lua_type (L, 3) == LUA_TNUMBER) {
mode = lua_tonumber (L, 3);
}
}
else if (lua_type (L, 2) == LUA_TNUMBER) {
/* Created fd */
fd = lua_tonumber (L, 2);
}

if (fd == -1) {
if (fname) {
fd = rspamd_file_xopen (fname, O_CREAT | O_WRONLY | O_EXCL, mode, 0);

if (fd == -1) {
lua_pushboolean (L, false);
lua_pushstring (L, strerror (errno));

return 2;
}
need_close = TRUE;
}
else {
fd = STDOUT_FILENO;
}
}

if (write (fd, t->start, t->len) == -1) {
if (fd != STDOUT_FILENO) {
close (fd);
}

lua_pushboolean (L, false);
lua_pushstring (L, strerror (errno));

return 2;
}

if (need_close) {
close (fd);
}

lua_pushboolean (L, true);
}
else {
return luaL_error (L, "invalid arguments");
}

return 1;
}

static gint
lua_text_gc (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);

if (t != NULL) {
if (t->flags & RSPAMD_TEXT_FLAG_OWN) {
if (t->flags & RSPAMD_TEXT_FLAG_WIPE) {
rspamd_explicit_memzero ((guchar *)t->start, t->len);
}

if (t->flags & RSPAMD_TEXT_FLAG_MMAPED) {
munmap ((gpointer)t->start, t->len);
}
else {
g_free ((gpointer)t->start);
}
}

}

return 0;
}

/* Init part */

static gint
@@ -6260,16 +5960,6 @@ lua_load_task (lua_State * L)
return 1;
}

static gint
lua_load_text (lua_State * L)
{
lua_newtable (L);
luaL_register (L, NULL, textlib_f);

return 1;
}


static void
luaopen_archive (lua_State * L)
{
@@ -6295,15 +5985,6 @@ luaopen_image (lua_State * L)
lua_pop (L, 1);
}

void
luaopen_text (lua_State *L)
{
rspamd_lua_new_class (L, "rspamd{text}", textlib_m);
lua_pop (L, 1);

rspamd_lua_add_preload (L, "rspamd_text", lua_load_text);
}

void
rspamd_lua_task_push (lua_State *L, struct rspamd_task *task)
{

+ 417
- 0
src/lua/lua_text.c Datei anzeigen

@@ -0,0 +1,417 @@
/*-
* Copyright 2019 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "lua_common.h"
#include "libcryptobox/cryptobox.h"
#include "unix-std.h"

/***
* @module rspamd_text
* This module provides access to opaque text structures used widely to prevent
* copying between Lua and C for various concerns: performance, security etc...
*
* You can convert rspamd_text into string but it will copy data.
*/

/**
* @function rspamd_text.fromstring(str)
* Creates rspamd_text from Lua string (copied to the text)
* @param {string} str string to use
* @return {rspamd_text} resulting text
*/
LUA_FUNCTION_DEF (text, fromstring);
/**
* @function rspamd_text.fromtable(tbl[, delim])
* Same as `table.concat` but generates rspamd_text instead of the Lua string
* @param {table} tbl table to use
* @param {string} delim optional delimiter
* @return {rspamd_text} resulting text
*/
LUA_FUNCTION_DEF (text, fromtable);
/***
* @method rspamd_text:len()
* Returns length of a string
* @return {number} length of string in **bytes**
*/
LUA_FUNCTION_DEF (text, len);
/***
* @method rspamd_text:str()
* Converts text to string by copying its content
* @return {string} copy of text as Lua string
*/
LUA_FUNCTION_DEF (text, str);
/***
* @method rspamd_text:ptr()
* Converts text to lightuserdata
* @return {lightuserdata} pointer value of rspamd_text
*/
LUA_FUNCTION_DEF (text, ptr);
/***
* @method rspamd_text:save_in_file(fname[, mode])
* Saves text in file
* @return {boolean} true if save has been completed
*/
LUA_FUNCTION_DEF (text, save_in_file);
LUA_FUNCTION_DEF (text, take_ownership);
LUA_FUNCTION_DEF (text, gc);
LUA_FUNCTION_DEF (text, eq);

static const struct luaL_reg textlib_f[] = {
LUA_INTERFACE_DEF (text, fromstring),
LUA_INTERFACE_DEF (text, fromtable),
{NULL, NULL}
};

static const struct luaL_reg textlib_m[] = {
LUA_INTERFACE_DEF (text, len),
LUA_INTERFACE_DEF (text, str),
LUA_INTERFACE_DEF (text, ptr),
LUA_INTERFACE_DEF (text, take_ownership),
LUA_INTERFACE_DEF (text, save_in_file),
{"write", lua_text_save_in_file},
{"__len", lua_text_len},
{"__tostring", lua_text_str},
{"__gc", lua_text_gc},
{"__eq", lua_text_eq},
{NULL, NULL}
};

static gint
lua_text_fromstring (lua_State *L)
{
LUA_TRACE_POINT;
const gchar *str;
gsize l = 0;
struct rspamd_lua_text *t;

str = luaL_checklstring (L, 1, &l);

if (str) {
t = lua_newuserdata (L, sizeof (*t));
t->start = g_malloc (l + 1);
rspamd_strlcpy ((char *)t->start, str, l + 1);
t->len = l;
t->flags = RSPAMD_TEXT_FLAG_OWN;
rspamd_lua_setclass (L, "rspamd{text}", -1);
}
else {
return luaL_error (L, "invalid arguments");
}


return 1;
}

static gint
lua_text_fromtable (lua_State *L)
{
LUA_TRACE_POINT;
const gchar *delim = "", *st;
struct rspamd_lua_text *t, *elt;
gsize textlen = 0, dlen, stlen, tblen;
gchar *dest;

if (!lua_istable (L, 1)) {
return luaL_error (L, "invalid arguments");
}

if (lua_type (L, 2) == LUA_TSTRING) {
delim = lua_tolstring (L, 2, &dlen);
}
else {
dlen = strlen (delim);
}

/* Calculate length needed */
tblen = rspamd_lua_table_size (L, 1);

for (guint i = 0; i < tblen; i ++) {
lua_rawgeti (L, 1, i + 1);

if (lua_type (L, -1) == LUA_TSTRING) {
#if LUA_VERSION_NUM >= 502
stlen = lua_rawlen (L, -1);
#else
stlen = lua_objlen (L, -1);
#endif
textlen += stlen;
}
else {
elt = lua_check_text (L, -1);

if (elt) {
textlen += elt->len;
}
}

lua_pop (L, 1);
textlen += dlen;
}

/* Allocate new text */
t = lua_newuserdata (L, sizeof (*t));
dest = g_malloc (textlen);
t->start = dest;
t->len = textlen;
t->flags = RSPAMD_TEXT_FLAG_OWN;
rspamd_lua_setclass (L, "rspamd{text}", -1);

for (guint i = 0; i < tblen; i ++) {
lua_rawgeti (L, 1, i + 1);

if (lua_type (L, -1) == LUA_TSTRING) {
st = lua_tolstring (L, -1, &stlen);
memcpy (dest, st, stlen);
dest += stlen;
}
else {
elt = lua_check_text (L, -1);

if (elt) {
memcpy (dest, elt->start, elt->len);
}
}

memcpy (dest, delim, dlen);
lua_pop (L, 1);
}

return 1;
}

static gint
lua_text_len (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);
gsize l = 0;

if (t != NULL) {
l = t->len;
}
else {
return luaL_error (L, "invalid arguments");
}

lua_pushinteger (L, l);

return 1;
}

static gint
lua_text_str (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);

if (t != NULL) {
lua_pushlstring (L, t->start, t->len);
}
else {
return luaL_error (L, "invalid arguments");
}

return 1;
}

static gint
lua_text_ptr (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);

if (t != NULL) {
lua_pushlightuserdata (L, (gpointer)t->start);
}
else {
return luaL_error (L, "invalid arguments");
}

return 1;
}

static gint
lua_text_take_ownership (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);
gchar *dest;

if (t != NULL) {
if (t->flags & RSPAMD_TEXT_FLAG_OWN) {
/* We already own it */
lua_pushboolean (L, true);
}
else {
dest = g_malloc (t->len);
memcpy (dest, t->start, t->len);
t->start = dest;
t->flags |= RSPAMD_TEXT_FLAG_OWN;
lua_pushboolean (L, true);
}
}
else {
return luaL_error (L, "invalid arguments");
}

return 1;
}

static gint
lua_text_save_in_file (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);
const gchar *fname = NULL;
guint mode = 00644;
gint fd = -1;
gboolean need_close = FALSE;

if (t != NULL) {
if (lua_type (L, 2) == LUA_TSTRING) {
fname = luaL_checkstring (L, 2);

if (lua_type (L, 3) == LUA_TNUMBER) {
mode = lua_tonumber (L, 3);
}
}
else if (lua_type (L, 2) == LUA_TNUMBER) {
/* Created fd */
fd = lua_tonumber (L, 2);
}

if (fd == -1) {
if (fname) {
fd = rspamd_file_xopen (fname, O_CREAT | O_WRONLY | O_EXCL, mode, 0);

if (fd == -1) {
lua_pushboolean (L, false);
lua_pushstring (L, strerror (errno));

return 2;
}
need_close = TRUE;
}
else {
fd = STDOUT_FILENO;
}
}

if (write (fd, t->start, t->len) == -1) {
if (fd != STDOUT_FILENO) {
close (fd);
}

lua_pushboolean (L, false);
lua_pushstring (L, strerror (errno));

return 2;
}

if (need_close) {
close (fd);
}

lua_pushboolean (L, true);
}
else {
return luaL_error (L, "invalid arguments");
}

return 1;
}

static gint
lua_text_gc (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);

if (t != NULL) {
if (t->flags & RSPAMD_TEXT_FLAG_OWN) {
if (t->flags & RSPAMD_TEXT_FLAG_WIPE) {
rspamd_explicit_memzero ((guchar *)t->start, t->len);
}

if (t->flags & RSPAMD_TEXT_FLAG_MMAPED) {
munmap ((gpointer)t->start, t->len);
}
else {
g_free ((gpointer)t->start);
}
}

}

return 0;
}

static gint
lua_text_eq (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t1 = lua_check_text (L, 1),
*t2 = lua_check_text (L, 2);

if (t1->len == t2->len) {
lua_pushboolean (L, memcmp (t1->start, t2->start, t1->len) == 0);
}
else {
lua_pushboolean (L, false);
}

return 1;
}

static gint
lua_text_wipe (lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_lua_text *t = lua_check_text (L, 1);

if (t != NULL) {
if (t->flags & RSPAMD_TEXT_FLAG_OWN) {
rspamd_explicit_memzero ((guchar *)t->start, t->len);
}
else {
return luaL_error (L, "cannot wipe not owned text");
}

}
else {
return luaL_error (L, "invalid arguments");
}

return 0;
}

static gint
lua_load_text (lua_State * L)
{
lua_newtable (L);
luaL_register (L, NULL, textlib_f);

return 1;
}

void
luaopen_text (lua_State *L)
{
rspamd_lua_new_class (L, "rspamd{text}", textlib_m);
lua_pop (L, 1);

rspamd_lua_add_preload (L, "rspamd_text", lua_load_text);
}

Laden…
Abbrechen
Speichern