Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup TestsuitesUnitNoClock0
0007  */
0008 
0009 /*
0010  * Copyright (C) 2023 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 #include <rtems/base64.h>
0035 
0036 #include <rtems/test.h>
0037 
0038 typedef struct {
0039   Base64_Decode_control base;
0040   uint8_t buf[64];
0041 } test_control;
0042 
0043 static int test_run(test_control* self, const char* payload) {
0044   size_t len = strlen(payload);
0045 
0046   for (size_t i = 0; i < len; ++i) {
0047     int rv = _Base64_Decode(&self->base, payload[i]);
0048 
0049     if (rv != 0) {
0050       return rv;
0051     }
0052   }
0053 
0054   return 0;
0055 }
0056 
0057 static int test_payload(test_control* self, const char* payload) {
0058   memset(self->buf, 0xff, sizeof(self->buf));
0059   _Base64_Decode_initialize(&self->base, &self->buf[0], sizeof(self->buf));
0060   return test_run(self, payload);
0061 }
0062 
0063 T_TEST_CASE(IOBase64Decode) {
0064   int rv;
0065   test_control instance;
0066   test_control* self = &instance;
0067 
0068   rv = test_payload(self, "POOL");
0069   T_eq_int(rv, BASE64_DECODE_SUCCESS);
0070   T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
0071   T_eq_ptr(self->base.target, &self->buf[3]);
0072   const uint8_t expected1[] = {0x3c, 0xe3, 0x8b, 0xff};
0073   T_eq_mem(&self->buf[0], expected1, sizeof(expected1));
0074 
0075   rv = test_payload(self, "ABCDEFGH");
0076   T_eq_int(rv, BASE64_DECODE_SUCCESS);
0077   T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
0078   T_eq_ptr(self->base.target, &self->buf[6]);
0079   const uint8_t expected2[] = {0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0xff};
0080   T_eq_mem(&self->buf[0], expected2, sizeof(expected2));
0081 
0082   /* Non-base64 character results in an error */
0083   rv = test_payload(self, "PO*OL");
0084   T_eq_int(rv, BASE64_DECODE_INVALID_INPUT);
0085   T_eq_int(self->base.state, BASE64_DECODE_STATE_2);
0086   T_eq_ptr(self->base.target, &self->buf[1]);
0087   const uint8_t expected3[] = {0x3c};
0088   T_eq_mem(&self->buf[0], expected3, sizeof(expected3));
0089 
0090   /* Other non-base64 character results in an error */
0091   rv = test_payload(self, "PO\x80OL");
0092   T_eq_int(rv, BASE64_DECODE_INVALID_INPUT);
0093   T_eq_int(self->base.state, BASE64_DECODE_STATE_2);
0094   T_eq_ptr(self->base.target, &self->buf[1]);
0095   T_eq_mem(&self->buf[0], expected3, sizeof(expected3));
0096 
0097   /* Space characters should be ignored */
0098   rv = test_payload(self, "P OOL");
0099   T_eq_int(rv, BASE64_DECODE_SUCCESS);
0100   T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
0101   T_eq_ptr(self->base.target, &self->buf[3]);
0102   const uint8_t expected4[] = {0x3c, 0xe3, 0x8b, 0xff};
0103   T_eq_mem(&self->buf[0], expected4, sizeof(expected4));
0104 
0105   /* Handle pad characters */
0106   rv = test_payload(self, "POOL==");
0107   T_eq_int(rv, BASE64_DECODE_SUCCESS);
0108   T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
0109   T_eq_ptr(self->base.target, &self->buf[3]);
0110   T_eq_ptr(self->base.target, self->base.target_end);
0111   const uint8_t expected5[] = {0x3c, 0xe3, 0x8b, 0xff};
0112   T_eq_mem(&self->buf[0], expected5, sizeof(expected5));
0113 
0114   /* If characters come after pad characters, an error results */
0115   rv = test_payload(self, "POOL==xy");
0116   T_eq_int(rv, BASE64_DECODE_OVERFLOW);
0117   T_eq_int(self->base.state, BASE64_DECODE_SUCCESS);
0118   T_eq_ptr(self->base.target, &self->buf[3]);
0119   T_eq_ptr(self->base.target, self->base.target_end);
0120   const uint8_t expected6[] = {0x3c, 0xe3, 0x8b, 0xff};
0121   T_eq_mem(&self->buf[0], expected6, sizeof(expected6));
0122 
0123   rv = test_payload(self, "POOLPOOL");
0124   T_eq_int(rv, BASE64_DECODE_SUCCESS);
0125   T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
0126   T_eq_ptr(self->base.target, &self->buf[6]);
0127   const uint8_t expected7[] = {0x3c, 0xe3, 0x8b, 0x3c, 0xe3, 0x8b, 0xff};
0128   T_eq_mem(&self->buf[0], expected7, sizeof(expected7));
0129 
0130   /*
0131    * Test valid payload with series of target sizes. All target sizes
0132    * less than three are invalid for the given payload and will result
0133    * in an error.
0134    */
0135   const uint8_t expected9[] = {0x3c, 0xe3, 0x8b, 0xff};
0136 
0137   for (size_t i = 0; i < 4; ++i) {
0138     memset(&self->buf[0], 0xff, sizeof(self->buf));
0139     _Base64_Decode_initialize(&self->base, &self->buf[0], i);
0140     rv = test_run(self, "POOL");
0141 
0142     if (i < 3) {
0143       T_eq_int(rv, BASE64_DECODE_OVERFLOW);
0144       T_eq_int(self->base.state, i);
0145       T_ne_ptr(self->base.target, &self->buf[3]);
0146       T_ne_mem(&self->buf[0], expected9, sizeof(expected9));
0147     } else {
0148       T_eq_int(rv, BASE64_DECODE_SUCCESS);
0149       T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
0150       T_eq_ptr(self->base.target, &self->buf[3]);
0151       T_eq_mem(&self->buf[0], expected9, sizeof(expected9));
0152     }
0153   }
0154 
0155   /* No overflow in state 1 */
0156   memset(&self->buf[0], 0xff, sizeof(self->buf));
0157   _Base64_Decode_initialize(&self->base, &self->buf[0], 1);
0158   rv = test_run(self, "AA");
0159   T_eq_int(rv, BASE64_DECODE_SUCCESS);
0160   T_eq_int(self->base.state, BASE64_DECODE_STATE_2);
0161   T_eq_ptr(self->base.target, &self->buf[1]);
0162   const uint8_t expected10[] = {0x00, 0xff};
0163   T_eq_mem(&self->buf[0], expected10, sizeof(expected10));
0164 
0165   /* No overflow in state 2 */
0166   memset(&self->buf[0], 0xff, sizeof(self->buf));
0167   _Base64_Decode_initialize(&self->base, &self->buf[0], 2);
0168   rv = test_run(self, "AAA");
0169   T_eq_int(rv, BASE64_DECODE_SUCCESS);
0170   T_eq_int(self->base.state, BASE64_DECODE_STATE_3);
0171   T_eq_ptr(self->base.target, &self->buf[2]);
0172   const uint8_t expected11[] = {0x00, 0x00, 0xff};
0173   T_eq_mem(&self->buf[0], expected11, sizeof(expected11));
0174 }
0175 
0176 T_TEST_CASE(IOBase64DecodeInitialize) {
0177   Base64_Decode_control instance;
0178   Base64_Decode_control* self = &instance;
0179   uint8_t buf[1];
0180 
0181   memset(self, 0xff, sizeof(*self));
0182   _Base64_Decode_initialize(self, buf, sizeof(buf));
0183   T_eq_int(self->state, BASE64_DECODE_STATE_0);
0184   T_eq_ptr(self->target, &buf[0]);
0185   T_eq_ptr(self->target_end, &buf[1]);
0186 }