From 3107af85a7c4152412410a2ffd7ce63c4fe75e61 Mon Sep 17 00:00:00 2001 From: Developer Alexander Date: Sun, 4 Dec 2022 10:58:36 +0100 Subject: [PATCH] lua: ByteArray integer parsing APIs Adds APIs for parsing different kinds of integer from a lua ByteArray: -16, 32 and 64 bit -singed or unsigned -encoded little endian or big endian --- epan/wslua/wslua_byte_array.c | 413 ++++++++++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) diff --git a/epan/wslua/wslua_byte_array.c b/epan/wslua/wslua_byte_array.c index bcf6c2e5bb..40f8dadd26 100644 --- a/epan/wslua/wslua_byte_array.c +++ b/epan/wslua/wslua_byte_array.c @@ -219,6 +219,407 @@ WSLUA_METHOD ByteArray_get_index(lua_State* L) { WSLUA_RETURN(1); /* The value [0-255] of the byte. */ } +WSLUA_METHOD ByteArray_get_le_int16(lua_State* L) { + /* Read a little endian encoded 16 bit signed integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 1) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + gint32 value = (gint32)ba->data[idx + 1]; + value <<= 8; + value |= (gint32)ba->data[idx]; + + lua_pushnumber(L, value); + + WSLUA_RETURN(1); /* The value of the little endian encoded 16 bit signed integer beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_le_int32(lua_State* L) { + /* Read a little endian encoded 32 bit signed integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 3) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + gint32 value = (gint32)ba->data[idx + 3]; + value <<= 8; + value |= (gint32)ba->data[idx + 2]; + value <<= 8; + value |= (gint32)ba->data[idx + 1]; + value <<= 8; + value |= (gint32)ba->data[idx]; + + lua_pushnumber(L, value); + + WSLUA_RETURN(1); /* The value of the little endian encoded 32 bit signed integer beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_le_int64(lua_State* L) { + /* Read a little endian encoded 64 bit signed integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 7) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + gint64 value = (gint64)ba->data[idx + 7]; + value <<= 8; + value |= (gint64)ba->data[idx + 6]; + value <<= 8; + value |= (gint64)ba->data[idx + 5]; + value <<= 8; + value |= (gint64)ba->data[idx + 4]; + value <<= 8; + value |= (gint64)ba->data[idx + 3]; + value <<= 8; + value |= (gint64)ba->data[idx + 2]; + value <<= 8; + value |= (gint64)ba->data[idx + 1]; + value <<= 8; + value |= (gint64)ba->data[idx]; + + pushInt64(L, value); + + WSLUA_RETURN(1); /* The value of the little endian encoded 64 bit signed integer as a <> object beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_le_uint16(lua_State* L) { + /* Read a little endian encoded 16 bit unsigned integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 1) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + guint32 value = (guint32)ba->data[idx + 1]; + value <<= 8; + value |= (guint32)ba->data[idx]; + + lua_pushnumber(L, value); + + WSLUA_RETURN(1); /* The value of the little endian encoded 16 bit unsigned integer beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_le_uint32(lua_State* L) { + /* Read a little endian encoded 32 bit unsigned integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 3) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + guint32 value = (guint32)ba->data[idx + 3]; + value <<= 8; + value |= (guint32)ba->data[idx + 2]; + value <<= 8; + value |= (guint32)ba->data[idx + 1]; + value <<= 8; + value |= (guint32)ba->data[idx]; + + lua_pushnumber(L, value); + + WSLUA_RETURN(1); /* The value of the little endian encoded 32 bit unsigned integer beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_le_uint64(lua_State* L) { + /* Read a little endian encoded 64 bit unsigned integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 7) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + guint64 value = (guint64)ba->data[idx + 7]; + value <<= 8; + value |= (guint64)ba->data[idx + 6]; + value <<= 8; + value |= (guint64)ba->data[idx + 5]; + value <<= 8; + value |= (guint64)ba->data[idx + 4]; + value <<= 8; + value |= (guint64)ba->data[idx + 3]; + value <<= 8; + value |= (guint64)ba->data[idx + 2]; + value <<= 8; + value |= (guint64)ba->data[idx + 1]; + value <<= 8; + value |= (guint64)ba->data[idx]; + + pushUInt64(L, value); + + WSLUA_RETURN(1); /* The value of the little endian encoded 64 bit unsigned integer as a <> object beginning at given index. */ +} + + +WSLUA_METHOD ByteArray_get_int16(lua_State* L) { + /* Read a little endian encoded 16 bit signed integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 1) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + gint32 value = (gint32)ba->data[idx]; + value <<= 8; + value |= (gint32)ba->data[idx + 1]; + + lua_pushnumber(L, value); + + WSLUA_RETURN(1); /* The value of the big endian encoded 16 bit signed integer beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_int32(lua_State* L) { + /* Read a big endian encoded 32 bit signed integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 3) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + gint32 value = (gint32)ba->data[idx]; + value <<= 8; + value |= (gint32)ba->data[idx + 1]; + value <<= 8; + value |= (gint32)ba->data[idx + 2]; + value <<= 8; + value |= (gint32)ba->data[idx + 3]; + + lua_pushnumber(L, value); + + WSLUA_RETURN(1); /* The value of the big endian encoded 32 bit signed integer beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_int64(lua_State* L) { + /* Read a big endian encoded 64 bit signed integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 7) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + gint64 value = (gint64)ba->data[idx]; + value <<= 8; + value |= (gint64)ba->data[idx + 1]; + value <<= 8; + value |= (gint64)ba->data[idx + 2]; + value <<= 8; + value |= (gint64)ba->data[idx + 3]; + value <<= 8; + value |= (gint64)ba->data[idx + 4]; + value <<= 8; + value |= (gint64)ba->data[idx + 5]; + value <<= 8; + value |= (gint64)ba->data[idx + 6]; + value <<= 8; + value |= (gint64)ba->data[idx + 7]; + + pushInt64(L, value); + + WSLUA_RETURN(1); /* The value of the big endian encoded 64 bit signed integer as a <> object beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_uint16(lua_State* L) { + /* Read a big endian encoded 16 bit unsigned integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 1) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + guint32 value = (guint32)ba->data[idx]; + value <<= 8; + value |= (guint32)ba->data[idx + 1]; + + lua_pushnumber(L, value); + + WSLUA_RETURN(1); /* The value of the big endian encoded 16 bit unsigned integer beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_uint32(lua_State* L) { + /* Read a big endian encoded 32 bit unsigned integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 3) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + guint32 value = (guint32)ba->data[idx]; + value <<= 8; + value |= (guint32)ba->data[idx + 1]; + value <<= 8; + value |= (guint32)ba->data[idx + 2]; + value <<= 8; + value |= (guint32)ba->data[idx + 3]; + + lua_pushnumber(L, value); + + WSLUA_RETURN(1); /* The value of the big endian encoded 32 bit unsigned integer beginning at given index. */ +} + +WSLUA_METHOD ByteArray_get_uint64(lua_State* L) { + /* Read a big endian encoded 64 bit unsigned integer in a <> beginning at given index. + + @since 4.1.0 + */ +#define WSLUA_ARG_ByteArray_get_index_INDEX 2 /* The position of the first byte. */ + ByteArray ba = checkByteArray(L, 1); + int idx = (int)luaL_checkinteger(L, WSLUA_ARG_ByteArray_get_index_INDEX); + + if (idx == 0 && !g_str_equal(luaL_optstring(L, 2, ""), "0")) { + luaL_argerror(L, 2, "bad index"); + return 0; + } + + if (idx < 0 || (guint)idx >= ba->len - 7) { + luaL_argerror(L, 2, "index out of range"); + return 0; + } + + guint64 value = (guint64)ba->data[idx]; + value <<= 8; + value |= (guint64)ba->data[idx + 1]; + value <<= 8; + value |= (guint64)ba->data[idx + 2]; + value <<= 8; + value |= (guint64)ba->data[idx + 3]; + value <<= 8; + value |= (guint64)ba->data[idx + 4]; + value <<= 8; + value |= (guint64)ba->data[idx + 5]; + value <<= 8; + value |= (guint64)ba->data[idx + 6]; + value <<= 8; + value |= (guint64)ba->data[idx + 7]; + + pushUInt64(L, value); + + WSLUA_RETURN(1); /* The value of the big endian encoded 64 bit unsigned integer as a <> object beginning at given index. */ +} + WSLUA_METHOD ByteArray_len(lua_State* L) { /* Obtain the length of a <>. */ ByteArray ba = checkByteArray(L,1); @@ -387,6 +788,18 @@ WSLUA_METHOD ByteArray_tvb (lua_State *L) { WSLUA_METHODS ByteArray_methods[] = { WSLUA_CLASS_FNREG(ByteArray,new), + WSLUA_CLASS_FNREG(ByteArray,get_le_int16), + WSLUA_CLASS_FNREG(ByteArray,get_le_int32), + WSLUA_CLASS_FNREG(ByteArray,get_le_int64), + WSLUA_CLASS_FNREG(ByteArray,get_le_uint16), + WSLUA_CLASS_FNREG(ByteArray,get_le_uint32), + WSLUA_CLASS_FNREG(ByteArray,get_le_uint64), + WSLUA_CLASS_FNREG(ByteArray,get_int16), + WSLUA_CLASS_FNREG(ByteArray,get_int32), + WSLUA_CLASS_FNREG(ByteArray,get_int64), + WSLUA_CLASS_FNREG(ByteArray,get_uint16), + WSLUA_CLASS_FNREG(ByteArray,get_uint32), + WSLUA_CLASS_FNREG(ByteArray,get_uint64), WSLUA_CLASS_FNREG(ByteArray,len), WSLUA_CLASS_FNREG(ByteArray,prepend), WSLUA_CLASS_FNREG(ByteArray,append),