authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2021-03-27 18:21:11+01:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2021-03-28 14:32:34+02:00
log6993087edceb0d80b120f8dd3927d77564f86cb3
treec23a416ba36033622b379621170d2cedf8eac556
parent99bed37fc7156edbca692f84eced575ec0c3846f

Remove the base64 unsafe decoder


3 files changed, 4 insertions(+), 88 deletions(-)

doc/langref.html.in+2-2
......@@ -9952,9 +9952,9 @@ export fn decode_base_64(
99529952) usize {
99539953 const src = source_ptr[0..source_len];
99549954 const dest = dest_ptr[0..dest_len];
9955 const base64_decoder = base64.standard.DecoderUnsafe;
9955 const base64_decoder = base64.standard.Decoder;
99569956 const decoded_size = base64_decoder.calcSizeForSlice(src) catch unreachable;
9957 base64_decoder.decode(dest[0..decoded_size], src);
9957 base64_decoder.decode(dest[0..decoded_size], src) catch unreachable;
99589958 return decoded_size;
99599959}
99609960 {#code_end#}
lib/std/base64.zig-84
......@@ -21,7 +21,6 @@ pub const Codecs = struct {
2121 decoderWithIgnore: fn (ignore: []const u8) Base64DecoderWithIgnore,
2222 Encoder: Base64Encoder,
2323 Decoder: Base64Decoder,
24 DecoderUnsafe: Base64DecoderUnsafe,
2524};
2625
2726pub const standard_alphabet_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".*;
......@@ -36,7 +35,6 @@ pub const standard = Codecs{
3635 .decoderWithIgnore = standardBase64DecoderWithIgnore,
3736 .Encoder = Base64Encoder.init(standard_alphabet_chars, '='),
3837 .Decoder = Base64Decoder.init(standard_alphabet_chars, '='),
39 .DecoderUnsafe = Base64DecoderUnsafe.init(standard_alphabet_chars, '='),
4038};
4139
4240/// Standard Base64 codecs, without padding
......@@ -46,7 +44,6 @@ pub const standard_no_pad = Codecs{
4644 .decoderWithIgnore = standardBase64DecoderWithIgnore,
4745 .Encoder = Base64Encoder.init(standard_alphabet_chars, null),
4846 .Decoder = Base64Decoder.init(standard_alphabet_chars, null),
49 .DecoderUnsafe = Base64DecoderUnsafe.init(standard_alphabet_chars, null),
5047};
5148
5249pub const url_safe_alphabet_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".*;
......@@ -61,7 +58,6 @@ pub const url_safe = Codecs{
6158 .decoderWithIgnore = urlSafeBase64DecoderWithIgnore,
6259 .Encoder = Base64Encoder.init(url_safe_alphabet_chars, '='),
6360 .Decoder = Base64Decoder.init(url_safe_alphabet_chars, '='),
64 .DecoderUnsafe = Base64DecoderUnsafe.init(url_safe_alphabet_chars, '='),
6561};
6662
6763/// URL-safe Base64 codecs, without padding
......@@ -71,7 +67,6 @@ pub const url_safe_no_pad = Codecs{
7167 .decoderWithIgnore = urlSafeBase64DecoderWithIgnore,
7268 .Encoder = Base64Encoder.init(url_safe_alphabet_chars, null),
7369 .Decoder = Base64Decoder.init(url_safe_alphabet_chars, null),
74 .DecoderUnsafe = Base64DecoderUnsafe.init(url_safe_alphabet_chars, null),
7570};
7671
7772// Backwards compatibility
......@@ -82,8 +77,6 @@ pub const standard_pad_char = standard.pad_char;
8277pub const standard_encoder = standard.Encoder;
8378/// Deprecated - Use `standard.Decoder`
8479pub const standard_decoder = standard.Decoder;
85/// Deprecated - Use `standard.DecoderUnsafe`
86pub const standard_decoder_unsafe = standard.DecoderUnsafe;
8780
8881pub const Base64Encoder = struct {
8982 alphabet_chars: [64]u8,
......@@ -323,75 +316,6 @@ pub const Base64DecoderWithIgnore = struct {
323316 }
324317};
325318
326pub const Base64DecoderUnsafe = struct {
327 /// e.g. 'A' => 0.
328 /// undefined for any value not in the 64 alphabet chars.
329 char_to_index: [256]u8,
330 pad_char: ?u8,
331
332 pub fn init(alphabet_chars: [64]u8, pad_char: ?u8) Base64DecoderUnsafe {
333 var result = Base64DecoderUnsafe{
334 .char_to_index = undefined,
335 .pad_char = pad_char,
336 };
337 for (alphabet_chars) |c, i| {
338 assert(pad_char == null or c != pad_char.?);
339 result.char_to_index[c] = @intCast(u8, i);
340 }
341 return result;
342 }
343
344 /// Return the exact decoded size for a slice.
345 /// `InvalidPadding` is returned if the input length is not valid.
346 pub fn calcSizeForSlice(decoder: *const Base64DecoderUnsafe, source: []const u8) Error!usize {
347 const safe_decoder = Base64Decoder{ .char_to_index = undefined, .pad_char = decoder.pad_char };
348 return safe_decoder.calcSizeForSlice(source);
349 }
350
351 /// dest.len must be what you get from ::calcDecodedSizeExactUnsafe.
352 /// invalid characters or padding will result in undefined values.
353 pub fn decode(decoder: *const Base64DecoderUnsafe, dest: []u8, source: []const u8) void {
354 assert(dest.len == decoder.calcSizeForSlice(source) catch unreachable);
355
356 var src_index: usize = 0;
357 var dest_index: usize = 0;
358 var in_buf_len: usize = source.len;
359
360 if (decoder.pad_char) |pad_char| {
361 while (in_buf_len > 0 and source[in_buf_len - 1] == pad_char) {
362 in_buf_len -= 1;
363 }
364 }
365
366 while (in_buf_len > 4) {
367 dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 | decoder.char_to_index[source[src_index + 1]] >> 4;
368 dest_index += 1;
369
370 dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 | decoder.char_to_index[source[src_index + 2]] >> 2;
371 dest_index += 1;
372
373 dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 | decoder.char_to_index[source[src_index + 3]];
374 dest_index += 1;
375
376 src_index += 4;
377 in_buf_len -= 4;
378 }
379
380 if (in_buf_len > 1) {
381 dest[dest_index] = decoder.char_to_index[source[src_index + 0]] << 2 | decoder.char_to_index[source[src_index + 1]] >> 4;
382 dest_index += 1;
383 }
384 if (in_buf_len > 2) {
385 dest[dest_index] = decoder.char_to_index[source[src_index + 1]] << 4 | decoder.char_to_index[source[src_index + 2]] >> 2;
386 dest_index += 1;
387 }
388 if (in_buf_len > 3) {
389 dest[dest_index] = decoder.char_to_index[source[src_index + 2]] << 6 | decoder.char_to_index[source[src_index + 3]];
390 dest_index += 1;
391 }
392 }
393};
394
395319test "base64" {
396320 @setEvalBranchQuota(8000);
397321 testBase64() catch unreachable;
......@@ -500,14 +424,6 @@ fn testAllApis(codecs: Codecs, expected_decoded: []const u8, expected_encoded: [
500424 testing.expect(written <= decoded.len);
501425 testing.expectEqualSlices(u8, expected_decoded, decoded[0..written]);
502426 }
503
504 // Base64DecoderUnsafe
505 {
506 var buffer: [0x100]u8 = undefined;
507 var decoded = buffer[0..try codecs.DecoderUnsafe.calcSizeForSlice(expected_encoded)];
508 codecs.DecoderUnsafe.decode(decoded, expected_encoded);
509 testing.expectEqualSlices(u8, expected_decoded, decoded);
510 }
511427}
512428
513429fn testDecodeIgnoreSpace(codecs: Codecs, expected_decoded: []const u8, encoded: []const u8) !void {
test/standalone/mix_o_files/base64.zig+2-2
......@@ -3,9 +3,9 @@ const base64 = @import("std").base64;
33export fn decode_base_64(dest_ptr: [*]u8, dest_len: usize, source_ptr: [*]const u8, source_len: usize) usize {
44 const src = source_ptr[0..source_len];
55 const dest = dest_ptr[0..dest_len];
6 const base64_decoder = base64.standard.DecoderUnsafe;
6 const base64_decoder = base64.standard.Decoder;
77 const decoded_size = base64_decoder.calcSizeForSlice(src) catch unreachable;
8 base64_decoder.decode(dest[0..decoded_size], src);
8 base64_decoder.decode(dest[0..decoded_size], src) catch unreachable;
99 return decoded_size;
1010}
1111