From a186143f628192156b2a9dcbf88ecaac758a9e0b Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 6 Jul 2023 15:38:08 -0700 Subject: [PATCH] Add EncodeHex() and DecodeHex() to Redbean --- libc/runtime/cocmd.c | 14 +++++----- test/net/https/mbedtls_test.c | 10 +++++++ test/tool/net/lfuncs_test.lua | 3 ++ third_party/lua/llex.c | 2 +- third_party/lua/lunix.c | 7 +++++ tool/net/help.txt | 13 +++++++-- tool/net/lfuncs.c | 52 +++++++++++++++++++++++++++++++++++ tool/net/lfuncs.h | 3 ++ tool/net/redbean.c | 6 ++-- 9 files changed, 97 insertions(+), 13 deletions(-) diff --git a/libc/runtime/cocmd.c b/libc/runtime/cocmd.c index 5972e4a87..ca63f15c3 100644 --- a/libc/runtime/cocmd.c +++ b/libc/runtime/cocmd.c @@ -235,11 +235,11 @@ static int Cd(void) { if (!chdir(s)) { return 0; } else { - tinyprint(2, "chdir: ", s, ": ", _strerdoc(errno), NULL); + tinyprint(2, "chdir: ", s, ": ", _strerdoc(errno), "\n", NULL); return 1; } } else { - tinyprint(2, "chdir: missing argument", NULL); + tinyprint(2, "chdir: missing argument\n", NULL); return 1; } } @@ -250,7 +250,7 @@ static int Mkdir(void) { if (n >= 3 && !strcmp(args[1], "-p")) ++i, f = makedirs; for (; i < n; ++i) { if (f(args[i], 0755)) { - tinyprint(2, "mkdir: ", args[i], ": ", _strerdoc(errno), NULL); + tinyprint(2, "mkdir: ", args[i], ": ", _strerdoc(errno), "\n", NULL); return errno; } } @@ -267,7 +267,7 @@ static int Kill(void) { } for (; i < n; ++i) { if (kill(atoi(args[i]), sig)) { - tinyprint(2, "kill: ", args[i], ": ", _strerdoc(errno), NULL); + tinyprint(2, "kill: ", args[i], ": ", _strerdoc(errno), "\n", NULL); rc = 1; } } @@ -325,7 +325,7 @@ static int Rm(void) { if (n > 1 && args[1][0] != '-') { for (i = 1; i < n; ++i) { if (unlink(args[i])) { - tinyprint(2, "rm: ", args[i], ": ", _strerdoc(errno), NULL); + tinyprint(2, "rm: ", args[i], ": ", _strerdoc(errno), "\n", NULL); return 1; } } @@ -340,7 +340,7 @@ static int Rmdir(void) { if (n > 1 && args[1][0] != '-') { for (i = 1; i < n; ++i) { if (rmdir(args[i])) { - tinyprint(2, "rmdir: ", args[i], ": ", _strerdoc(errno), NULL); + tinyprint(2, "rmdir: ", args[i], ": ", _strerdoc(errno), "\n", NULL); return 1; } } @@ -355,7 +355,7 @@ static int Touch(void) { if (n > 1 && args[1][0] != '-') { for (i = 1; i < n; ++i) { if (touch(args[i], 0644)) { - tinyprint(2, "touch: ", args[i], ": ", _strerdoc(errno), NULL); + tinyprint(2, "touch: ", args[i], ": ", _strerdoc(errno), "\n", NULL); return 1; } } diff --git a/test/net/https/mbedtls_test.c b/test/net/https/mbedtls_test.c index a30cc3b61..bbbb4fbdf 100644 --- a/test/net/https/mbedtls_test.c +++ b/test/net/https/mbedtls_test.c @@ -27,6 +27,7 @@ #include "libc/runtime/runtime.h" #include "libc/stdio/rand.h" #include "libc/str/blake2.h" +#include "libc/str/highwayhash64.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/hyperion.h" #include "libc/testlib/testlib.h" @@ -266,6 +267,13 @@ TEST(sha512, test) { EXPECT_EQ(0, memcmp(want, d, 64)); } +static const uint64_t kTestKey1[4] = { + 0x0706050403020100, + 0x0F0E0D0C0B0A0908, + 0x1716151413121110, + 0x1F1E1D1C1B1A1918, +}; + BENCH(mbedtls, bench) { uint8_t d[64]; EZBENCH_N("md5", kHyperionSize, mbedtls_md5_ret(kHyperion, kHyperionSize, d)); @@ -280,6 +288,8 @@ BENCH(mbedtls, bench) { EZBENCH_N("blake2b256", kHyperionSize, BLAKE2B256(kHyperion, kHyperionSize, d)); EZBENCH_N("crc32_z", kHyperionSize, crc32_z(0, kHyperion, kHyperionSize)); + EZBENCH_N("highwayhash64", kHyperionSize, + HighwayHash64(kHyperion, kHyperionSize, kTestKey1)); } char *mpi2str(mbedtls_mpi *m) { diff --git a/test/tool/net/lfuncs_test.lua b/test/tool/net/lfuncs_test.lua index e05eea6a4..871869cbf 100644 --- a/test/tool/net/lfuncs_test.lua +++ b/test/tool/net/lfuncs_test.lua @@ -47,6 +47,9 @@ assert(hex(0x1940efe9d47ae889) == "0x1940efe9d47ae889") assert(oct(0x1940efe9d47ae889) == "0145007376472436564211") assert(bin(0x1940efe9d47ae889) == "0b0001100101000000111011111110100111010100011110101110100010001001") +assert(EncodeHex("\1\2\3\4\255") == "01020304ff") +assert(DecodeHex("01020304ff") == "\1\2\3\4\255") + assert(EscapeHtml(nil) == nil) assert(EscapeHtml("?hello&there<>") == "?hello&there<>") diff --git a/third_party/lua/llex.c b/third_party/lua/llex.c index 337adf666..7907a089b 100644 --- a/third_party/lua/llex.c +++ b/third_party/lua/llex.c @@ -27,11 +27,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #define llex_c #define LUA_CORE +#include "third_party/lua/llex.h" #include "third_party/lua/lctype.h" #include "third_party/lua/ldebug.h" #include "third_party/lua/ldo.h" #include "third_party/lua/lgc.h" -#include "third_party/lua/llex.h" #include "third_party/lua/lobject.h" #include "third_party/lua/lparser.h" #include "third_party/lua/lprefix.h" diff --git a/third_party/lua/lunix.c b/third_party/lua/lunix.c index 4484325ee..30b81cc53 100644 --- a/third_party/lua/lunix.c +++ b/third_party/lua/lunix.c @@ -2020,6 +2020,12 @@ static int LuaUnixSchedYield(lua_State *L) { return 0; } +// unix.verynice() +static int LuaUnixVerynice(lua_State *L) { + verynice(); + return 0; +} + //////////////////////////////////////////////////////////////////////////////// // unix.Stat object @@ -3338,6 +3344,7 @@ static const luaL_Reg kLuaUnix[] = { {"unlink", LuaUnixUnlink}, // remove file {"unveil", LuaUnixUnveil}, // filesystem sandboxing {"utimensat", LuaUnixUtimensat}, // change access/modified time + {"verynice", LuaUnixVerynice}, // lowest priority {"wait", LuaUnixWait}, // wait for child to change status {"write", LuaUnixWrite}, // write to file or socket {0}, // diff --git a/tool/net/help.txt b/tool/net/help.txt index cd88bab9e..84db6da0c 100644 --- a/tool/net/help.txt +++ b/tool/net/help.txt @@ -721,14 +721,21 @@ FUNCTIONS A granular. It can tell you if traffic originated from private networks, ARIN, APNIC, DOD, etc. + DecodeLatin1(iso-8859-1:str) → utf-8:str + Turns ISO-8859-1 string into UTF-8. + + EncodeHex(binary:str) → ascii:str + Turns binary into ASCII base-16 hexadecimal lowercase string. + + DecodeHex(ascii:str) → binary:str + Turns ASCII base-16 hexadecimal byte string into binary string, + case-insensitively. Non-hex characters may not appear in string. + DecodeBase64(ascii:str) → binary:str Turns ASCII into binary, in a permissive way that ignores characters outside the base64 alphabet, such as whitespace. See decodebase64.c. - DecodeLatin1(iso-8859-1:str) → utf-8:str - Turns ISO-8859-1 string into UTF-8. - EncodeBase64(binary:str) → ascii:str Turns binary into ASCII. This can be used to create HTML data: URIs that do things like embed a PNG file in a web page. See diff --git a/tool/net/lfuncs.c b/tool/net/lfuncs.c index c5c719f45..60561081e 100644 --- a/tool/net/lfuncs.c +++ b/tool/net/lfuncs.c @@ -42,8 +42,10 @@ #include "libc/runtime/runtime.h" #include "libc/sock/sock.h" #include "libc/stdio/rand.h" +#include "libc/str/highwayhash64.h" #include "libc/str/str.h" #include "libc/str/strwidth.h" +#include "libc/str/tab.internal.h" #include "libc/sysv/consts/af.h" #include "libc/sysv/consts/ipproto.h" #include "libc/sysv/consts/o.h" @@ -355,6 +357,20 @@ int LuaBsf(lua_State *L) { } } +int LuaHighwayHash64(lua_State *L) { + long i; + size_t n; + uint64_t k[4]; + const char *p; + p = luaL_checklstring(L, 1, &n); + k[0] = luaL_optinteger(L, 2, 0); + k[1] = luaL_optinteger(L, 3, 0); + k[2] = luaL_optinteger(L, 4, 0); + k[3] = luaL_optinteger(L, 5, 0); + lua_pushinteger(L, HighwayHash64(p, n, k)); + return 1; +} + static int LuaHash(lua_State *L, uint32_t H(uint32_t, const void *, size_t)) { long i; size_t n; @@ -586,6 +602,42 @@ int LuaEncodeLatin1(lua_State *L) { } } +int LuaEncodeHex(lua_State *L) { + char *p; + size_t n; + const char *s; + luaL_Buffer buf; + s = luaL_checklstring(L, 1, &n); + p = luaL_buffinitsize(L, &buf, n * 2 + 1); + hexpcpy(p, s, n); + luaL_pushresultsize(&buf, n * 2); + return 1; +} + +int LuaDecodeHex(lua_State *L) { + char *p; + int x, y; + size_t i, n; + const char *s; + luaL_Buffer buf; + s = luaL_checklstring(L, 1, &n); + if (n & 1) { + luaL_argerror(L, 1, "hex string length uneven"); + __builtin_unreachable(); + } + p = luaL_buffinitsize(L, &buf, n >> 1); + for (i = 0; i < n; i += 2) { + if ((x = kHexToInt[s[i + 0] & 255]) == -1 || + (y = kHexToInt[s[i + 1] & 255]) == -1) { + luaL_argerror(L, 1, "hex string has non-hex character"); + __builtin_unreachable(); + } + p[i >> 1] = x << 4 | y; + } + luaL_pushresultsize(&buf, n >> 1); + return 1; +} + int LuaGetRandomBytes(lua_State *L) { size_t n; luaL_Buffer buf; diff --git a/tool/net/lfuncs.h b/tool/net/lfuncs.h index 0f19dcf3d..76d2d1d37 100644 --- a/tool/net/lfuncs.h +++ b/tool/net/lfuncs.h @@ -21,9 +21,11 @@ int LuaCrc32(lua_State *); int LuaCrc32c(lua_State *); int LuaDecimate(lua_State *); int LuaDecodeBase64(lua_State *); +int LuaDecodeHex(lua_State *); int LuaDecodeLatin1(lua_State *); int LuaDeflate(lua_State *); int LuaEncodeBase64(lua_State *); +int LuaEncodeHex(lua_State *); int LuaEncodeLatin1(lua_State *); int LuaEscapeFragment(lua_State *); int LuaEscapeHost(lua_State *); @@ -50,6 +52,7 @@ int LuaGetRandomBytes(lua_State *); int LuaGetTime(lua_State *); int LuaHasControlCodes(lua_State *); int LuaHex(lua_State *); +int LuaHighwayHash64(lua_State *); int LuaIndentLines(lua_State *); int LuaInflate(lua_State *); int LuaIsAcceptableHost(lua_State *); diff --git a/tool/net/redbean.c b/tool/net/redbean.c index b3d43f9c1..161dbfc51 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -2556,8 +2556,7 @@ static char *ServeErrorImpl(unsigned code, const char *reason, static char *ServeErrorWithPath(unsigned code, const char *reason, const char *path, size_t pathlen) { - ERRORF("(srvr) server error: %d %s %`'.*s", code, reason, - pathlen, path); + ERRORF("(srvr) server error: %d %s %`'.*s", code, reason, pathlen, path); return ServeErrorImpl(code, reason, NULL); } @@ -5128,10 +5127,12 @@ static const luaL_Reg kLuaFuncs[] = { {"Crc32c", LuaCrc32c}, // {"Decimate", LuaDecimate}, // {"DecodeBase64", LuaDecodeBase64}, // + {"DecodeHex", LuaDecodeHex}, // {"DecodeJson", LuaDecodeJson}, // {"DecodeLatin1", LuaDecodeLatin1}, // {"Deflate", LuaDeflate}, // {"EncodeBase64", LuaEncodeBase64}, // + {"EncodeHex", LuaEncodeHex}, // {"EncodeJson", LuaEncodeJson}, // {"EncodeLatin1", LuaEncodeLatin1}, // {"EncodeLua", LuaEncodeLua}, // @@ -5193,6 +5194,7 @@ static const luaL_Reg kLuaFuncs[] = { {"HasControlCodes", LuaHasControlCodes}, // {"HasParam", LuaHasParam}, // {"HidePath", LuaHidePath}, // + {"HighwayHash64", LuaHighwayHash64}, // {"IndentLines", LuaIndentLines}, // {"Inflate", LuaInflate}, // {"IsAcceptableHost", LuaIsAcceptableHost}, //