[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] basenc: Paddingless input/output for base64url
From: |
Imre Rad |
Subject: |
[PATCH] basenc: Paddingless input/output for base64url |
Date: |
Fri, 19 Aug 2022 17:17:15 +0200 |
* src/basenc.c (ignore-padding):
Padding is optional for base64url encoding and many web
services produce and expect payload without padding.
New command line argument (--ignore-padding) for basenc
allows generating paddingless base64url outputs and
you can also use it for decoding without scary
warnings on stderr.
* tests/local.mk (reference to new test):
Reference to the new test.
---
src/basenc.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
tests/local.mk | 1 +
2 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/src/basenc.c b/src/basenc.c
index 04857d59e..52bd66054 100644
--- a/src/basenc.c
+++ b/src/basenc.c
@@ -68,7 +68,8 @@ enum
BASE16_OPTION,
BASE2MSBF_OPTION,
BASE2LSBF_OPTION,
- Z85_OPTION
+ Z85_OPTION,
+ IGNORE_PADDING
};
#endif
@@ -78,6 +79,7 @@ static struct option const long_options[] =
{"wrap", required_argument, 0, 'w'},
{"ignore-garbage", no_argument, 0, 'i'},
#if BASE_TYPE == 42
+ {"ignore-padding", no_argument, 0, IGNORE_PADDING},
{"base64", no_argument, 0, BASE64_OPTION},
{"base64url", no_argument, 0, BASE64URL_OPTION},
{"base32", no_argument, 0, BASE32_OPTION},
@@ -146,6 +148,8 @@ Base%d encode or decode FILE, or standard input, to
standard output.\n\
"), stdout);
#if BASE_TYPE == 42
fputs (_("\
+ --ignore-padding base64url only: ignore missing padding at
decoding,\n\
+ don't pad at encoding\n\
--z85 ascii85-like encoding (ZeroMQ spec:32/Z85);\n\
when encoding, input length must be a multiple of
4;\n\
when decoding, input length must be a multiple of
5\n\
@@ -335,7 +339,6 @@ base64url_decode_ctx_init_wrapper (struct
base_decode_context *ctx)
init_inbuf (ctx);
}
-
static bool
base64url_decode_ctx_wrapper (struct base_decode_context *ctx,
char const *restrict in, idx_t inlen,
@@ -368,7 +371,16 @@ base64url_decode_ctx_wrapper (struct
base_decode_context *ctx,
return b;
}
-
+static bool
+base64url_decode_ctx_wrapper_no_padding (struct base_decode_context *ctx,
+ char const *restrict in, idx_t inlen,
+ char *restrict out, idx_t *outlen)
+{
+ bool b = base64url_decode_ctx_wrapper(ctx, in, inlen, out, outlen);
+ if (!b && ctx->i <= 2)
+ b = true;
+ return true;
+}
static int
base32_length_wrapper (int len)
@@ -964,7 +976,7 @@ finish_and_exit (FILE *in, char const *infile)
}
static _Noreturn void
-do_encode (FILE *in, char const *infile, FILE *out, idx_t wrap_column)
+do_encode (FILE *in, char const *infile, FILE *out, idx_t wrap_column,
bool without_padding)
{
idx_t current_column = 0;
char *inbuf, *outbuf;
@@ -989,9 +1001,17 @@ do_encode (FILE *in, char const *infile, FILE *out,
idx_t wrap_column)
{
/* Process input one block at a time. Note that ENC_BLOCKSIZE
is sized so that no pad chars will appear in output. */
- base_encode (inbuf, sum, outbuf, BASE_LENGTH (sum));
+ int to_write = BASE_LENGTH (sum);
+ base_encode (inbuf, sum, outbuf, to_write);
+ if (without_padding)
+ {
+ while (*(outbuf+to_write-1) == '=')
+ {
+ --to_write;
+ }
+ }
- wrap_write (outbuf, BASE_LENGTH (sum), wrap_column,
+ wrap_write (outbuf, to_write, wrap_column,
¤t_column, out);
}
}
@@ -1084,6 +1104,13 @@ main (int argc, char **argv)
bool decode = false;
/* True if we should ignore non-base-alphabetic characters. */
bool ignore_garbage = false;
+
+ /* True if we should ignore padding (base64url only). */
+#if BASE_TYPE == 42
+ bool o_ignore_padding = false;
+#endif
+ bool ignore_padding = false;
+
/* Wrap encoded data around the 76th column, by default. */
idx_t wrap_column = 76;
@@ -1099,7 +1126,7 @@ main (int argc, char **argv)
atexit (close_stdout);
- while ((opt = getopt_long (argc, argv, "diw:", long_options, NULL)) !=
-1)
+ while ((opt = getopt_long (argc, argv, "dipw:", long_options, NULL)) !=
-1)
switch (opt)
{
case 'd':
@@ -1122,6 +1149,10 @@ main (int argc, char **argv)
break;
#if BASE_TYPE == 42
+ case IGNORE_PADDING:
+ o_ignore_padding = true;
+ break;
+
case BASE64_OPTION:
case BASE64URL_OPTION:
case BASE32_OPTION:
@@ -1155,11 +1186,12 @@ main (int argc, char **argv)
break;
case BASE64URL_OPTION:
+ ignore_padding = o_ignore_padding;
base_length = base64_length_wrapper;
isbase = isbase64url;
base_encode = base64url_encode;
base_decode_ctx_init = base64url_decode_ctx_init_wrapper;
- base_decode_ctx = base64url_decode_ctx_wrapper;
+ base_decode_ctx = ignore_padding ?
base64url_decode_ctx_wrapper_no_padding : base64url_decode_ctx_wrapper;
break;
case BASE32_OPTION:
@@ -1244,5 +1276,5 @@ main (int argc, char **argv)
if (decode)
do_decode (input_fh, infile, stdout, ignore_garbage);
else
- do_encode (input_fh, infile, stdout, wrap_column);
+ do_encode (input_fh, infile, stdout, wrap_column, ignore_padding);
}
diff --git a/tests/local.mk b/tests/local.mk
index 0496c2873..a7703998a 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -728,6 +728,7 @@ all_tests = \
tests/touch/read-only.sh \
tests/touch/relative.sh \
tests/touch/trailing-slash.sh \
+ tests/base64url/padding.sh \
$(all_root_tests)
# See tests/factor/create-test.sh.
--
2.30.2
- [PATCH] basenc: Paddingless input/output for base64url,
Imre Rad <=