소스 검색

mg.base64_decode for Lua

bel 11 년 전
부모
커밋
b72ad2cbe6
2개의 변경된 파일79개의 추가작업 그리고 3개의 파일을 삭제
  1. 42 1
      src/civetweb.c
  2. 37 2
      src/mod_lua.inl

+ 42 - 1
src/civetweb.c

@@ -2300,6 +2300,47 @@ static void base64_encode(const unsigned char *src, int src_len, char *dst)
     }
     dst[j++] = '\0';
 }
+
+static unsigned char b64reverse(char letter) {
+    if (letter>='A' && letter<='Z') return letter-'A';
+    if (letter>='a' && letter<='z') return letter-'a'+26;
+    if (letter>='0' && letter<='9') return letter-'0'+52;
+    if (letter=='+') return 62;
+    if (letter=='/') return 63;
+    if (letter=='=') return 255; /* normal end */
+    return 254; /* error */
+}
+
+static int base64_decode(const unsigned char *src, int src_len, char *dst, size_t *dst_len)
+{
+    int i;
+    unsigned char a, b, c, d;
+
+    *dst_len = 0;
+
+    for (i = 0; i < src_len; i += 4) {
+        a = b64reverse(src[i]);
+        if (a>=254) return i;
+
+        b = b64reverse(i + 1 >= src_len ? 0 : src[i + 1]);
+        if (b>=254) return i+1;
+
+        c = b64reverse(i + 2 >= src_len ? 0 : src[i + 2]);
+        if (c==254) return i+2;
+
+        d = b64reverse(i + 3 >= src_len ? 0 : src[i + 3]);
+        if (c==254) return i+3;
+
+        dst[(*dst_len)++] = (a << 2) + (b >> 4);
+        if (c!=255) {
+            dst[(*dst_len)++] = (b << 4) + (c >> 2);
+            if (d!=255) {
+                dst[(*dst_len)++] = (c << 6) + d;
+            }
+        }
+    }
+    return -1;
+}
 #endif
 
 static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
@@ -2789,7 +2830,7 @@ static int parse_auth_header(struct mg_connection *conn, char *buf,
 
 #ifndef NO_NONCE_CHECK
     /* Convert the nonce from the client to a number and check it. */
-    /* Server side nonce check is valuable in all situations but one: if the server restarts frequently, 
+    /* Server side nonce check is valuable in all situations but one: if the server restarts frequently,
        but the client should not see that, so the server should accept nonces from previous starts. */
     nonce = strtoul(ah->nonce, &s, 10);
     if ((s == NULL) || (*s != 0)) {

+ 37 - 2
src/mod_lua.inl

@@ -588,6 +588,41 @@ static int lsp_base64_encode(lua_State *L)
     return 1;
 }
 
+/* mg.base64_encode */
+static int lsp_base64_decode(lua_State *L)
+{
+    int num_args = lua_gettop(L);
+    const char *text;
+    size_t text_len, dst_len;
+    int ret;
+    char *dst;
+
+    if (num_args==1) {
+        text = lua_tolstring(L, 1, &text_len);
+        if (text) {
+            dst = malloc(text_len);
+            if (dst) {
+                ret = base64_decode(text, text_len, dst, &dst_len);
+                if (ret != -1) {
+                    free(dst);
+                    return luaL_error(L, "illegal character in lsp_base64_decode() call");
+                } else {
+                    lua_pushlstring(L, dst, dst_len);
+                    free(dst);
+                }
+            } else {
+                return luaL_error(L, "out of memory in lsp_base64_decode() call");
+            }
+        } else {
+            lua_pushnil(L);
+        }
+    } else {
+        /* Syntax error */
+        return luaL_error(L, "invalid lsp_base64_decode() call");
+    }
+    return 1;
+}
+
 /* mg.write for websockets */
 static int lwebsock_write(lua_State *L)
 {
@@ -707,7 +742,7 @@ static void prepare_lua_environment(struct mg_connection *conn, lua_State *L, co
     reg_function(L, "url_encode", lsp_url_encode, conn);
     reg_function(L, "url_decode", lsp_url_decode, conn);
     reg_function(L, "base64_encode", lsp_base64_encode, conn);
-    //reg_function(L, "base64_decode", lsp_base64_decode, conn);
+    reg_function(L, "base64_decode", lsp_base64_decode, conn);
 
     reg_string(L, "version", CIVETWEB_VERSION);
     reg_string(L, "document_root", conn->ctx->config[DOCUMENT_ROOT]);
@@ -755,7 +790,7 @@ static void prepare_lua_environment(struct mg_connection *conn, lua_State *L, co
     /* Preload */
     if ((preload_file != NULL) && (*preload_file != 0)) {
         IGNORE_UNUSED_RESULT(luaL_dofile(L, preload_file));
-    }    
+    }
 }
 
 static int lua_error_handler(lua_State *L)