Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:10

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSImplBase64
0007  *
0008  * @brief This source file contains the implementation of
0009  *   _Base64_Decode_initialize() and _Base64_Decode().
0010  */
0011 
0012 /*
0013  * Copyright (C) 2023 embedded brains GmbH & Co. KG
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
0035  */
0036 
0037 #include <rtems/base64.h>
0038 
0039 #define SPACE 253
0040 
0041 #define PAD 254
0042 
0043 #define INVALID 255
0044 
0045 const uint8_t _Base64_Decoding[128] = {
0046     ['A'] = 0,       ['B'] = 1,       ['C'] = 2,       ['D'] = 3,
0047     ['E'] = 4,       ['F'] = 5,       ['G'] = 6,       ['H'] = 7,
0048     ['I'] = 8,       ['J'] = 9,       ['K'] = 10,      ['L'] = 11,
0049     ['M'] = 12,      ['N'] = 13,      ['O'] = 14,      ['P'] = 15,
0050     ['Q'] = 16,      ['R'] = 17,      ['S'] = 18,      ['T'] = 19,
0051     ['U'] = 20,      ['V'] = 21,      ['W'] = 22,      ['X'] = 23,
0052     ['Y'] = 24,      ['Z'] = 25,      ['a'] = 26,      ['b'] = 27,
0053     ['c'] = 28,      ['d'] = 29,      ['e'] = 30,      ['f'] = 31,
0054     ['g'] = 32,      ['h'] = 33,      ['i'] = 34,      ['j'] = 35,
0055     ['k'] = 36,      ['l'] = 37,      ['m'] = 38,      ['n'] = 39,
0056     ['o'] = 40,      ['p'] = 41,      ['q'] = 42,      ['r'] = 43,
0057     ['s'] = 44,      ['t'] = 45,      ['u'] = 46,      ['v'] = 47,
0058     ['w'] = 48,      ['x'] = 49,      ['y'] = 50,      ['z'] = 51,
0059     ['0'] = 52,      ['1'] = 53,      ['2'] = 54,      ['3'] = 55,
0060     ['4'] = 56,      ['5'] = 57,      ['6'] = 58,      ['7'] = 59,
0061     ['8'] = 60,      ['9'] = 61,      ['+'] = 62,      ['-'] = 62,
0062     ['/'] = 63,      ['_'] = 63,      ['='] = PAD,     [' '] = SPACE,
0063     ['\t'] = SPACE,  ['\n'] = SPACE,  ['\v'] = SPACE,  ['\f'] = SPACE,
0064     ['\r'] = SPACE,  [0] = INVALID,   [1] = INVALID,   [2] = INVALID,
0065     [3] = INVALID,   [4] = INVALID,   [5] = INVALID,   [6] = INVALID,
0066     [7] = INVALID,   [8] = INVALID,   [14] = INVALID,  [15] = INVALID,
0067     [16] = INVALID,  [17] = INVALID,  [18] = INVALID,  [19] = INVALID,
0068     [20] = INVALID,  [21] = INVALID,  [22] = INVALID,  [23] = INVALID,
0069     [24] = INVALID,  [25] = INVALID,  [26] = INVALID,  [27] = INVALID,
0070     [28] = INVALID,  [29] = INVALID,  [30] = INVALID,  [31] = INVALID,
0071     [33] = INVALID,  [34] = INVALID,  [35] = INVALID,  [36] = INVALID,
0072     [37] = INVALID,  [38] = INVALID,  [39] = INVALID,  [40] = INVALID,
0073     [41] = INVALID,  [42] = INVALID,  [44] = INVALID,  [46] = INVALID,
0074     [58] = INVALID,  [59] = INVALID,  [60] = INVALID,  [62] = INVALID,
0075     [63] = INVALID,  [64] = INVALID,  [91] = INVALID,  [92] = INVALID,
0076     [93] = INVALID,  [94] = INVALID,  [96] = INVALID,  [123] = INVALID,
0077     [124] = INVALID, [125] = INVALID, [126] = INVALID, [127] = INVALID};
0078 
0079 void _Base64_Decode_initialize(Base64_Decode_control* self,
0080                                uint8_t* target,
0081                                size_t target_size) {
0082   self->state = BASE64_DECODE_STATE_0;
0083   self->target = target;
0084   self->target_end = target + target_size;
0085 }
0086 
0087 Base64_Decode_status _Base64_Decode(Base64_Decode_control* self, char ch) {
0088   uint8_t decoded_ch;
0089   uint8_t next_ch;
0090   uint8_t* target;
0091   const uint8_t* target_end;
0092   Base64_Decode_state next_state;
0093 
0094   if ((unsigned char)ch >= 128) {
0095     return BASE64_DECODE_INVALID_INPUT;
0096   }
0097 
0098   decoded_ch = _Base64_Decoding[(unsigned char)ch];
0099 
0100   if (decoded_ch == SPACE) {
0101     return BASE64_DECODE_SUCCESS;
0102   }
0103 
0104   target = self->target;
0105 
0106   if (decoded_ch == PAD) {
0107     self->target_end = target;
0108     return BASE64_DECODE_SUCCESS;
0109   }
0110 
0111   if (decoded_ch == INVALID) {
0112     return BASE64_DECODE_INVALID_INPUT;
0113   }
0114 
0115   target_end = self->target_end;
0116 
0117   if (target == target_end) {
0118     return BASE64_DECODE_OVERFLOW;
0119   }
0120 
0121   switch (self->state) {
0122     case BASE64_DECODE_STATE_0:
0123       *target = decoded_ch << 2;
0124       next_state = BASE64_DECODE_STATE_1;
0125       break;
0126 
0127     case BASE64_DECODE_STATE_1:
0128       *target |= decoded_ch >> 4;
0129       next_ch = (decoded_ch & 0x0fU) << 4;
0130       ++target;
0131 
0132       if (target != target_end) {
0133         *target = next_ch;
0134       } else if (next_ch != 0) {
0135         return BASE64_DECODE_OVERFLOW;
0136       }
0137 
0138       next_state = BASE64_DECODE_STATE_2;
0139       break;
0140 
0141     case BASE64_DECODE_STATE_2:
0142       *target |= decoded_ch >> 2;
0143       next_ch = (decoded_ch & 0x03U) << 6;
0144       ++target;
0145 
0146       if (target != target_end) {
0147         *target = next_ch;
0148       } else if (next_ch != 0) {
0149         return BASE64_DECODE_OVERFLOW;
0150       }
0151 
0152       next_state = BASE64_DECODE_STATE_3;
0153       break;
0154 
0155     default: /* BASE64_DECODE_STATE_3 */
0156       *target |= decoded_ch;
0157       ++target;
0158       next_state = BASE64_DECODE_STATE_0;
0159       break;
0160   }
0161 
0162   self->state = next_state;
0163   self->target = target;
0164   return BASE64_DECODE_SUCCESS;
0165 }