From 848c3749d2b68cf936680f1b90d57085586a9006 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 26 May 2025 12:23:54 +0200 Subject: [PATCH 1/7] change function definitions Buffers are no longer wired into any input or translation functions. They are supplied as arguments through main. --- input.c | 34 +++++++++++++--------------------- input.h | 11 ++++------- main.c | 31 ++++++++++++++++++++----------- trans.c | 27 ++++++++++++--------------- trans.h | 10 ++++------ 5 files changed, 53 insertions(+), 60 deletions(-) diff --git a/input.c b/input.c index 855445a..7b97223 100644 --- a/input.c +++ b/input.c @@ -1,37 +1,29 @@ #include "input.h" -#define OBUFSIZE 4 -#define SBUFSIZE 5 - #define PADDING '=' -unsigned char o[OBUFSIZE]; -unsigned char s[SBUFSIZE]; - -unsigned char * -getocts(FILE *fp, int *np) +int +getocts(FILE *fp, unsigned char *o, int olen) { - int n, c; + int c, n; n = 0; - while (n < OBUFSIZE-1 && (c = fgetc(fp)) != EOF) + while (n < olen-1 && (c = fgetc(fp)) != EOF) o[n++] = c; - *np = n; - return (*np) ? o : NULL; + return n; } -unsigned char * -getsxts(FILE *fp, int *np) +int +getsxts(FILE *fp, unsigned char *s, int slen) { - int n, p, c; + int c, n, pad; - n = p = 0; - while (n < SBUFSIZE-1 && (c = fgetc(fp)) != EOF && c != PADDING) + n = pad = 0; + while (n < slen-1 && (c = fgetc(fp)) != EOF && c != PADDING) s[n++] = c; - while (n+p < SBUFSIZE-1) - s[n+p++] = PADDING; - *np = n; + while (n+pad < slen-1) + s[n+pad++] = PADDING; - return (n) ? s : NULL; + return n; } diff --git a/input.h b/input.h index 178f17b..42bd4a6 100644 --- a/input.h +++ b/input.h @@ -3,13 +3,10 @@ #include -extern unsigned char o[]; -extern unsigned char s[]; +int +getocts(FILE *fp, unsigned char *o, int olen); -unsigned char * -getocts(FILE *fp, int *np); - -unsigned char * -getsxts(FILE *fp, int *np); +int +getsxts(FILE *fp, unsigned char *s, int slen); #endif diff --git a/main.c b/main.c index b657c99..a0cbc32 100644 --- a/main.c +++ b/main.c @@ -3,12 +3,17 @@ #include "input.h" #include "trans.h" +#define OBUFSIZE 4 +#define SBUFSIZE 5 + +unsigned char obuf[OBUFSIZE]; +unsigned char sbuf[SBUFSIZE]; + int main(int argc, char *argv[]) { int c, n, dec, hlp; char *prog = *argv; - unsigned char *b; FILE *fp; dec = hlp = 0; @@ -30,13 +35,15 @@ main(int argc, char *argv[]) fprintf(stdout, "Usage: %s -d -h file\n", prog); } else if (argc != 1) { if (dec) { - while ((b = getsxts(stdin, &n))) { - b = decode(b, &n); - fwrite(b, sizeof(*b), n, stdout); + while ((n = getsxts(stdin, sbuf, SBUFSIZE))) { + n = decode(sbuf, n, obuf); + fwrite(obuf, sizeof(*obuf), n, stdout); } } else { - while ((b = getocts(stdin, &n))) - printf("%s", encode(b, n)); + while ((n = getocts(stdin, obuf, OBUFSIZE))) { + encode(obuf, n, sbuf); + printf("%s", sbuf); + } } } else { if ((fp = fopen(*argv, "r")) == NULL) { @@ -44,13 +51,15 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } else if (dec) { - while ((b = getsxts(fp, &n))) { - b = decode(b, &n); - fwrite(b, sizeof(*b), n, stdout); + while ((n = getsxts(fp, sbuf, SBUFSIZE))) { + n = decode(sbuf, n, obuf); + fwrite(obuf, sizeof(*obuf), n, stdout); } } else { - while ((b = getocts(fp, &n))) - printf("%s", encode(b, n)); + while ((n = getocts(fp, obuf, OBUFSIZE))) { + encode(obuf, n, sbuf); + printf("%s", sbuf); + } } fclose(fp); } diff --git a/trans.c b/trans.c index c29c576..6b48e0b 100644 --- a/trans.c +++ b/trans.c @@ -7,15 +7,14 @@ unsigned char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "0123456789" \ "+/"; -unsigned char * -encode(unsigned char *op, int np) +int +encode(unsigned char *op, int olen, unsigned char *sp) { - extern unsigned char s[]; - unsigned char *sp; int n; + unsigned char *sb; - sp = s; - switch (np) { + sb = sp; + switch (olen) { case 3: *sp++ = b64[(*op & ~3) >> 2]; n = (*op++ & 3) << 4; @@ -39,18 +38,17 @@ encode(unsigned char *op, int np) break; } - return s; + return sp-sb+1; } -unsigned char * -decode(unsigned char *sp, int *np) +int +decode(unsigned char *sp, int slen, unsigned char *op) { - extern unsigned char o[]; - unsigned char *op; int n, b, atob(int c); + unsigned char *ob; - op = o; - switch (*np) { + ob = op; + switch (slen) { case 4: n = atob(*sp++) << 2; b = atob(*sp++); @@ -75,9 +73,8 @@ decode(unsigned char *sp, int *np) *op = n + ((atob(*sp) & ~15) >> 4); break; } - *np = op-o+1; - return o; + return op-ob+1; } int atob(int c) diff --git a/trans.h b/trans.h index 845a2d2..3b4fa5c 100644 --- a/trans.h +++ b/trans.h @@ -1,12 +1,10 @@ #ifndef HEADER_TRANS #define HEADER_TRANS -#include "input.h" +int +encode(unsigned char *op, int olen, unsigned char *sp); -unsigned char * -encode(unsigned char *op, int np); - -unsigned char * -decode(unsigned char *sp, int *np); +int +decode(unsigned char *sp, int slen, unsigned char *op); #endif From 221a8588c0080978c716f42d8191e6738ab9e99f Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 26 May 2025 22:38:33 +0200 Subject: [PATCH 2/7] add writing to file output option --- main.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/main.c b/main.c index a0cbc32..77dd98a 100644 --- a/main.c +++ b/main.c @@ -14,7 +14,7 @@ main(int argc, char *argv[]) { int c, n, dec, hlp; char *prog = *argv; - FILE *fp; + FILE *in, *out; dec = hlp = 0; while (--argc > 0 && (*++argv)[0] == '-') @@ -32,36 +32,31 @@ main(int argc, char *argv[]) break; } if (hlp) { - fprintf(stdout, "Usage: %s -d -h file\n", prog); - } else if (argc != 1) { - if (dec) { - while ((n = getsxts(stdin, sbuf, SBUFSIZE))) { - n = decode(sbuf, n, obuf); - fwrite(obuf, sizeof(*obuf), n, stdout); - } - } else { - while ((n = getocts(stdin, obuf, OBUFSIZE))) { - encode(obuf, n, sbuf); - printf("%s", sbuf); - } - } + fprintf(stdout, "Usage: %s -d -h infile outfile\n", prog); } else { - if ((fp = fopen(*argv, "r")) == NULL) { + if (argc >= 1 && (in = fopen(*argv, "r")) == NULL) { fprintf(stderr, "%s: can't open %s\n", prog, *argv); exit(EXIT_FAILURE); } - else if (dec) { - while ((n = getsxts(fp, sbuf, SBUFSIZE))) { + if (argc == 2 && (out = fopen(*(argv+1), "w")) == NULL) { + fprintf(stderr, "%s: can't open %s\n", prog, *(argv+1)); + exit(EXIT_FAILURE); + } + if (dec) { + while ((n = getsxts((argc >= 1) ? in : stdin, sbuf, SBUFSIZE))) { n = decode(sbuf, n, obuf); - fwrite(obuf, sizeof(*obuf), n, stdout); + fwrite(obuf, sizeof(*obuf), n, (argc == 2) ? out : stdout); } } else { - while ((n = getocts(fp, obuf, OBUFSIZE))) { + while ((n = getocts((argc >= 1) ? in : stdin, obuf, OBUFSIZE))) { encode(obuf, n, sbuf); - printf("%s", sbuf); + fprintf((argc == 2) ? out : stdout, "%s", sbuf); } } - fclose(fp); + if (in) + fclose(in); + if (out) + fclose(out); } exit(EXIT_SUCCESS); } From 28fcd5ed7a22314ae06546b4d0f11b96ace8398a Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 26 May 2025 23:12:16 +0200 Subject: [PATCH 3/7] change file trans.{c,h} to encode.{c,h} --- Makefile | 6 +++--- trans.c => encode.c | 2 +- trans.h => encode.h | 4 ++-- main.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename trans.c => encode.c (99%) rename trans.h => encode.h (74%) diff --git a/Makefile b/Makefile index a870852..4567eca 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ CFLAGS = -g -Wall -Wextra -Werror -objects = main.o input.o trans.o +objects = main.o input.o encode.o b64 : $(objects) cc -o b64 $(objects) -main.o trans.o input.o : input.h -main.o trans.o : trans.h +main.o encode.o input.o : input.h +main.o encode.o : encode.h .PHONY : clean clean : diff --git a/trans.c b/encode.c similarity index 99% rename from trans.c rename to encode.c index 6b48e0b..576f9f3 100644 --- a/trans.c +++ b/encode.c @@ -1,4 +1,4 @@ -#include "trans.h" +#include "encode.h" #define PADDING '=' diff --git a/trans.h b/encode.h similarity index 74% rename from trans.h rename to encode.h index 3b4fa5c..f211396 100644 --- a/trans.h +++ b/encode.h @@ -1,5 +1,5 @@ -#ifndef HEADER_TRANS -#define HEADER_TRANS +#ifndef HEADER_ENCODE +#define HEADER_ENCODE int encode(unsigned char *op, int olen, unsigned char *sp); diff --git a/main.c b/main.c index 77dd98a..ff16bf6 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ #include #include #include "input.h" -#include "trans.h" +#include "encode.h" #define OBUFSIZE 4 #define SBUFSIZE 5 From 8991fe1a69c7b31f3b5f0c1e346446702dd344e1 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 26 May 2025 23:14:39 +0200 Subject: [PATCH 4/7] correct Makefile recipe for encode.o Since 848c37 encode.o no longer requires input.h. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4567eca..d71ad1c 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ objects = main.o input.o encode.o b64 : $(objects) cc -o b64 $(objects) -main.o encode.o input.o : input.h +main.o input.o : input.h main.o encode.o : encode.h .PHONY : clean From a91be306b1fbe2534f9d8c8ceb7b143042fb1083 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 26 May 2025 23:59:47 +0200 Subject: [PATCH 5/7] add base64url encoding option --- encode.c | 54 ++++++++++++++++++++++++++++++------------------------ encode.h | 4 ++-- main.c | 11 +++++++---- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/encode.c b/encode.c index 576f9f3..cee611f 100644 --- a/encode.c +++ b/encode.c @@ -7,32 +7,38 @@ unsigned char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "0123456789" \ "+/"; +unsigned char b64u[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "abcdefghijklmnopqrstuvwxyz" \ + "0123456789" \ + "-_"; + int -encode(unsigned char *op, int olen, unsigned char *sp) +encode(unsigned char *op, int olen, unsigned char *sp, int url) { int n; - unsigned char *sb; + unsigned char *sb, *enc; sb = sp; + enc = (!url) ? b64 : b64u; switch (olen) { case 3: - *sp++ = b64[(*op & ~3) >> 2]; + *sp++ = enc[(*op & ~3) >> 2]; n = (*op++ & 3) << 4; - *sp++ = b64[n + ((*op & ~15) >> 4)]; + *sp++ = enc[n + ((*op & ~15) >> 4)]; n = (*op++ & 15) << 2; - *sp++ = b64[n + ((*op & 192) >> 6)]; - *sp = b64[*op & ~192]; + *sp++ = enc[n + ((*op & 192) >> 6)]; + *sp = enc[*op & ~192]; break; case 2: - *sp++ = b64[(*op & ~3) >> 2]; + *sp++ = enc[(*op & ~3) >> 2]; n = (*op++ & 3) << 4; - *sp++ = b64[n + ((*op & ~15) >> 4)]; - *sp++ = b64[(*op & 15) << 2]; + *sp++ = enc[n + ((*op & ~15) >> 4)]; + *sp++ = enc[(*op & 15) << 2]; *sp = PADDING; break; case 1: - *sp++ = b64[(*op & ~3) >> 2]; - *sp++ = b64[(*op & 3) << 4]; + *sp++ = enc[(*op & ~3) >> 2]; + *sp++ = enc[(*op & 3) << 4]; *sp++ = PADDING; *sp = PADDING; break; @@ -42,42 +48,42 @@ encode(unsigned char *op, int olen, unsigned char *sp) } int -decode(unsigned char *sp, int slen, unsigned char *op) +decode(unsigned char *sp, int slen, unsigned char *op, int url) { - int n, b, atob(int c); + int n, b, atob(int c, int url); unsigned char *ob; ob = op; switch (slen) { case 4: - n = atob(*sp++) << 2; - b = atob(*sp++); + n = atob(*sp++, url) << 2; + b = atob(*sp++, url); *op++ = n + ((b & ~15) >> 4); n = (b & 15) << 4; - b = atob(*sp++); + b = atob(*sp++, url); *op++ = n + ((b & ~3) >> 2); - *op = ((b & 3) << 6) + atob(*sp); + *op = ((b & 3) << 6) + atob(*sp, url); break; case 3: - n = atob(*sp++) << 2; - b = atob(*sp++); + n = atob(*sp++, url) << 2; + b = atob(*sp++, url); *op++ = n + ((b & ~15) >> 4); n = (b & 15) << 4; - *op = n + ((atob(*sp) & ~3) >> 2); + *op = n + ((atob(*sp, url) & ~3) >> 2); break; case 2: - n = atob(*sp++) << 2; - *op = n + ((atob(*sp) & ~15) >> 4); + n = atob(*sp++, url) << 2; + *op = n + ((atob(*sp, url) & ~15) >> 4); break; } return op-ob+1; } -int atob(int c) +int atob(int c, int url) { if (c >= 'A' && c <= 'Z') c -= 'A'; @@ -85,7 +91,7 @@ int atob(int c) c = c - 'a' + 26; else if (c >= '0' && c <= '9') c = c - '0' + 26 * 2; - else if (c == '+') + else if (c == ((!url) ? '+' : '-')) c = 62; else c = 63; diff --git a/encode.h b/encode.h index f211396..2ea285a 100644 --- a/encode.h +++ b/encode.h @@ -2,9 +2,9 @@ #define HEADER_ENCODE int -encode(unsigned char *op, int olen, unsigned char *sp); +encode(unsigned char *op, int olen, unsigned char *sp, int url); int -decode(unsigned char *sp, int slen, unsigned char *op); +decode(unsigned char *sp, int slen, unsigned char *op, int url); #endif diff --git a/main.c b/main.c index ff16bf6..b48684c 100644 --- a/main.c +++ b/main.c @@ -12,17 +12,20 @@ unsigned char sbuf[SBUFSIZE]; int main(int argc, char *argv[]) { - int c, n, dec, hlp; + int c, n, dec, url, hlp; char *prog = *argv; FILE *in, *out; - dec = hlp = 0; + dec = url = hlp = 0; while (--argc > 0 && (*++argv)[0] == '-') while ((c = *++argv[0])) switch (c) { case 'd': dec = 1; break; + case 'u': + url = 1; + break; case 'h': hlp = 1; break; @@ -44,12 +47,12 @@ main(int argc, char *argv[]) } if (dec) { while ((n = getsxts((argc >= 1) ? in : stdin, sbuf, SBUFSIZE))) { - n = decode(sbuf, n, obuf); + n = decode(sbuf, n, obuf, url); fwrite(obuf, sizeof(*obuf), n, (argc == 2) ? out : stdout); } } else { while ((n = getocts((argc >= 1) ? in : stdin, obuf, OBUFSIZE))) { - encode(obuf, n, sbuf); + encode(obuf, n, sbuf, url); fprintf((argc == 2) ? out : stdout, "%s", sbuf); } } From 623d0a5c3bce0a6971c358fcbea6c93bb39f4eb6 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 27 May 2025 00:14:33 +0200 Subject: [PATCH 6/7] add newline recognition for encoded input --- input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/input.c b/input.c index 7b97223..cfe80b1 100644 --- a/input.c +++ b/input.c @@ -21,7 +21,8 @@ getsxts(FILE *fp, unsigned char *s, int slen) n = pad = 0; while (n < slen-1 && (c = fgetc(fp)) != EOF && c != PADDING) - s[n++] = c; + if (c != '\n') + s[n++] = c; while (n+pad < slen-1) s[n+pad++] = PADDING; From 6c7d699f1a02f6f6c8b6e830e4ff69f8e22a9313 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 27 May 2025 00:27:25 +0200 Subject: [PATCH 7/7] add newline to end of file when encoding --- main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/main.c b/main.c index b48684c..9cb544c 100644 --- a/main.c +++ b/main.c @@ -55,6 +55,7 @@ main(int argc, char *argv[]) encode(obuf, n, sbuf, url); fprintf((argc == 2) ? out : stdout, "%s", sbuf); } + fprintf((argc == 2) ? out : stdout, "\n"); } if (in) fclose(in);