removes openssl dependencies for base64

Wed, 13 Dec 2017 19:48:44 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 13 Dec 2017 19:48:44 +0100
changeset 344
72791e299d64
parent 338
c7f3fe4abdb2
child 345
61c4576072b3

removes openssl dependencies for base64

dav/tar.c file | annotate | diff | comparison | revisions
libidav/davqlexec.h file | annotate | diff | comparison | revisions
libidav/utils.c file | annotate | diff | comparison | revisions
--- a/dav/tar.c	Sun Dec 03 13:09:14 2017 +0100
+++ b/dav/tar.c	Wed Dec 13 19:48:44 2017 +0100
@@ -93,18 +93,18 @@
     // name
     memcpy(h.name, name.ptr, name.length);
     // mode
-    snprintf(h.mode, 8, "%0.7o", mode);
+    snprintf(h.mode, 8, "%07o", mode);
     h.mode[7] = ' ';
     // uid/gid
     memset(h.uid, '0', 16);
     h.uid[7] = ' ';
     h.gid[7] = ' ';
     // size
-    snprintf(h.size, 12, "%0.11lo", size);
+    snprintf(h.size, 12, "%011lo", size);
     h.size[11] = ' ';
     // mtime
     uint64_t t = (uint64_t)mtime;
-    snprintf(h.mtime, 12, "%0.11lo", mtime);
+    snprintf(h.mtime, 12, "%011lo", mtime);
     h.mtime[11] = ' ';
     // chksum
     memset(h.chksum, ' ', 8);
@@ -118,7 +118,7 @@
     h.version[1] = '0';
     // uname/gname - zero
     // devmajor/devminor
-    snprintf(h.devmajor, 16, "%0.15o", 0);
+    snprintf(h.devmajor, 16, "%015o", 0);
     h.devmajor[7] = ' ';
     h.devminor[7] = ' ';
     // prefix
@@ -130,7 +130,7 @@
     for(int i=0;i<512;i++) {
         chksum += header[i];
     }
-    snprintf(h.chksum, 8, "%0.7o", chksum);
+    snprintf(h.chksum, 8, "%07o", chksum);
     
     fwrite(&h, 1, 512, tar->file);
     
--- a/libidav/davqlexec.h	Sun Dec 03 13:09:14 2017 +0100
+++ b/libidav/davqlexec.h	Wed Dec 13 19:48:44 2017 +0100
@@ -37,7 +37,7 @@
 #ifdef	__cplusplus
 extern "C" {
 #endif
-
+    
 typedef struct DavQLCmd      DavQLCmd;
 typedef struct DavQLStackObj DavQLStackObj;
 typedef struct DavQLRes      DavQLRes;
--- a/libidav/utils.c	Sun Dec 03 13:09:14 2017 +0100
+++ b/libidav/utils.c	Wed Dec 13 19:48:44 2017 +0100
@@ -466,41 +466,139 @@
     return util_base64decode_len(in, &len);
 }
 
+#define WHITESPACE 64
+#define EQUALS     65
+#define INVALID    66
+static char b64dectable[] = {
+    66,66,66,66,66,66,66,66,66,66,64,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+    66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,62,66,66,66,63,52,53,
+    54,55,56,57,58,59,60,61,66,66,66,65,66,66,66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+    10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,66,66,66,66,66,66,26,27,28,
+    29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,66,66,
+    66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+    66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+    66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+    66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+    66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+    66,66,66,66,66,66
+};
 char* util_base64decode_len(char* in, int *outlen) {
-    size_t len = strlen(in);
-    char *out = calloc(1, len);
+    /* code is mostly from wikibooks */
+    
+    size_t inlen = strlen(in);
+    size_t bufsize = (inlen*3) / 4;
+    char *outbuf = malloc(bufsize+1);
+    *outlen = -1;
+    
+    unsigned char *out = outbuf;
+    
+    char *end = in + inlen;
+    char iter = 0;
+    uint32_t buf = 0;
+    size_t len = 0;
     
-    BIO *b = BIO_new_mem_buf(in, len);
-    BIO *d = BIO_new(BIO_f_base64());
-    BIO_set_flags(d, BIO_FLAGS_BASE64_NO_NL);
-    b = BIO_push(d, b);
+    while (in < end) {
+        unsigned char c = b64dectable[*in++];
+        
+        switch (c) {
+            case WHITESPACE: continue; /* skip whitespace */
+            case INVALID: {
+                  /* invalid input */
+                outbuf[0] = 0;
+                return outbuf;
+            }
+            case EQUALS: {
+                /* pad character, end of data */
+                in = end;
+                continue;
+            }
+            default: {
+                buf = buf << 6 | c;
+                iter++; // increment the number of iteration
+                /* If the buffer is full, split it into bytes */
+                if (iter == 4) {
+                    if ((len += 3) > bufsize) {
+                        /* buffer overflow */
+                        outbuf[0] = 0;
+                        return outbuf;
+                    }
+                    *(out++) = (buf >> 16) & 255;
+                    *(out++) = (buf >> 8) & 255;
+                    *(out++) = buf & 255;
+                    buf = 0; iter = 0;
 
-    *outlen = BIO_read(b, out, len);
-    BIO_free_all(b);
-    
-    return out;
+                }
+            }
+        }
+    }
+   
+    if (iter == 3) {
+        if ((len += 2) > bufsize) {
+            /* buffer overflow */
+            outbuf[0] = 0;
+            return outbuf;
+        }
+        *(out++) = (buf >> 10) & 255;
+        *(out++) = (buf >> 2) & 255;
+    }
+    else if (iter == 2) {
+        if (++len > bufsize) {
+            /* buffer overflow */
+            outbuf[0] = 0;
+            return outbuf;
+        }
+        *(out++) = (buf >> 4) & 255;
+    }
+
+    *outlen = len; /* modify to reflect the actual output size */
+    outbuf[len] = 0;
+    return outbuf;
 }
 
-char* util_base64encode(char *in, size_t len) { 
-    BIO *b;
-    BIO *e;
-    BUF_MEM *mem;
 
-    e = BIO_new(BIO_f_base64());
-    b = BIO_new(BIO_s_mem());
-    BIO_set_flags(e, BIO_FLAGS_BASE64_NO_NL);
+static char* b64enctable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+char* util_base64encode(char *in, size_t len) {
+    // calculate length of base64 output and create buffer
+    size_t outlen = 4 * ((len + 2) / 3);
+    int pad = len % 3;
+    
+    char *out = malloc(outlen + 1);
+    out[outlen] = 0;
+    size_t pos = 0;
     
-    e = BIO_push(e, b);
-    BIO_write(e, in, len);
-    BIO_flush(e);
+    // encode blocks of 3 bytes
+    size_t i;
+    size_t blockend = len - pad;
+    for(i=0;i<blockend;i++) {
+        unsigned char b1 = in[i++];
+        unsigned char b2 = in[i++];
+        unsigned char b3 = in[i];
+        uint32_t inb = b1 << 16 | (b2 << 8) | b3;
+        out[pos++] = b64enctable[(inb >> 18) & 63];
+        out[pos++] = b64enctable[(inb >> 12) & 63];
+        out[pos++] = b64enctable[(inb >> 6) & 63];
+        out[pos++] = b64enctable[(inb) & 63];
+    }
     
-    BIO_get_mem_ptr(e, &mem);
-    char *out = malloc(mem->length + 1);
-    memcpy(out, mem->data, mem->length);
-    out[mem->length] = '\0';
-
-    BIO_free_all(e);
-
+    // encode last bytes
+    if(pad > 0) {
+        char p[3] = {0, 0, 0};
+        for(int j=0;i<len;i++) {
+            p[j++] = in[i];
+        }
+        unsigned char b1 = p[0];
+        unsigned char b2 = p[1];
+        unsigned char b3 = p[2];
+        uint32_t inb = (b1 << 16) | (b2 << 8) | b3;
+        out[pos++] = b64enctable[(inb >> 18) & 63];
+        out[pos++] = b64enctable[(inb >> 12) & 63];
+        out[pos++] = b64enctable[(inb >> 6) & 63];
+        out[pos++] = b64enctable[(inb) & 63];
+        for(int k=outlen-1;k>=outlen-(3-pad);k--) {
+            out[k] = '=';
+        }
+    }
+    
     return out;
 }
 

mercurial