Matter SDK Coverage Report
Current view: top level - setup_payload - Base38Decode.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 100.0 % 39 39
Test Date: 2025-01-17 19:00:11 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : /**
      19              :  *    @file
      20              :  *      This file implements converting a Base38 String into an array of bytes.
      21              :  *
      22              :  */
      23              : 
      24              : #include "Base38Decode.h"
      25              : 
      26              : namespace {
      27              : 
      28          687 : static inline CHIP_ERROR decodeChar(char c, uint8_t & value)
      29              : {
      30              :     static const int kBogus = 255;
      31              :     // map of base38 charater to numeric value
      32              :     // subtract 45 from the charater, then index into this array, if possible
      33          687 :     const uint8_t decodes[] = {
      34              :         36,     // '-', =45
      35              :         37,     // '.', =46
      36              :         kBogus, // '/', =47
      37              :         0,      // '0', =48
      38              :         1,      // '1', =49
      39              :         2,      // '2', =50
      40              :         3,      // '3', =51
      41              :         4,      // '4', =52
      42              :         5,      // '5', =53
      43              :         6,      // '6', =54
      44              :         7,      // '7', =55
      45              :         8,      // '8', =56
      46              :         9,      // '9', =57
      47              :         kBogus, // ':', =58
      48              :         kBogus, // ';', =59
      49              :         kBogus, // '<', =50
      50              :         kBogus, // '=', =61
      51              :         kBogus, // '>', =62
      52              :         kBogus, // '?', =63
      53              :         kBogus, // '@', =64
      54              :         10,     // 'A', =65
      55              :         11,     // 'B', =66
      56              :         12,     // 'C', =67
      57              :         13,     // 'D', =68
      58              :         14,     // 'E', =69
      59              :         15,     // 'F', =70
      60              :         16,     // 'G', =71
      61              :         17,     // 'H', =72
      62              :         18,     // 'I', =73
      63              :         19,     // 'J', =74
      64              :         20,     // 'K', =75
      65              :         21,     // 'L', =76
      66              :         22,     // 'M', =77
      67              :         23,     // 'N', =78
      68              :         24,     // 'O', =79
      69              :         25,     // 'P', =80
      70              :         26,     // 'Q', =81
      71              :         27,     // 'R', =82
      72              :         28,     // 'S', =83
      73              :         29,     // 'T', =84
      74              :         30,     // 'U', =85
      75              :         31,     // 'V', =86
      76              :         32,     // 'W', =87
      77              :         33,     // 'X', =88
      78              :         34,     // 'Y', =89
      79              :         35,     // 'Z', =90
      80              :     };
      81          687 :     if (c < '-' || c > 'Z')
      82              :     {
      83           18 :         return CHIP_ERROR_INVALID_INTEGER_VALUE;
      84              :     }
      85          669 :     uint8_t v = decodes[c - '-'];
      86          669 :     if (v == kBogus)
      87              :     {
      88            5 :         return CHIP_ERROR_INVALID_INTEGER_VALUE;
      89              :     }
      90          664 :     value = v;
      91          664 :     return CHIP_NO_ERROR;
      92              : }
      93              : 
      94              : } // unnamed namespace
      95              : 
      96              : namespace chip {
      97              : 
      98           59 : CHIP_ERROR base38Decode(std::string base38, std::vector<uint8_t> & result)
      99              : {
     100           59 :     result.clear();
     101              : 
     102           59 :     size_t base38CharactersNumber  = base38.length();
     103           59 :     size_t decodedBase38Characters = 0;
     104          194 :     while (base38CharactersNumber > 0)
     105              :     {
     106              :         uint8_t base38CharactersInChunk;
     107              :         uint8_t bytesInDecodedChunk;
     108              : 
     109          162 :         if (base38CharactersNumber >= kBase38CharactersNeededInNBytesChunk[2])
     110              :         {
     111          108 :             base38CharactersInChunk = kBase38CharactersNeededInNBytesChunk[2];
     112          108 :             bytesInDecodedChunk     = 3;
     113              :         }
     114           54 :         else if (base38CharactersNumber == kBase38CharactersNeededInNBytesChunk[1])
     115              :         {
     116           23 :             base38CharactersInChunk = kBase38CharactersNeededInNBytesChunk[1];
     117           23 :             bytesInDecodedChunk     = 2;
     118              :         }
     119           31 :         else if (base38CharactersNumber == kBase38CharactersNeededInNBytesChunk[0])
     120              :         {
     121           30 :             base38CharactersInChunk = kBase38CharactersNeededInNBytesChunk[0];
     122           30 :             bytesInDecodedChunk     = 1;
     123              :         }
     124              :         else
     125              :         {
     126            1 :             return CHIP_ERROR_INVALID_STRING_LENGTH;
     127              :         }
     128              : 
     129          161 :         uint32_t value = 0;
     130              : 
     131          825 :         for (size_t i = base38CharactersInChunk; i > 0; i--)
     132              :         {
     133          687 :             uint8_t v      = 0;
     134          687 :             CHIP_ERROR err = decodeChar(base38[decodedBase38Characters + i - 1], v);
     135              : 
     136          687 :             if (err != CHIP_NO_ERROR)
     137              :             {
     138           23 :                 return err;
     139              :             }
     140              : 
     141          664 :             value = value * kRadix + v;
     142              :         }
     143          138 :         decodedBase38Characters += base38CharactersInChunk;
     144          138 :         base38CharactersNumber -= base38CharactersInChunk;
     145              : 
     146          514 :         for (size_t i = 0; i < bytesInDecodedChunk; i++)
     147              :         {
     148          376 :             result.push_back(static_cast<uint8_t>(value));
     149          376 :             value >>= 8;
     150              :         }
     151              : 
     152          138 :         if (value > 0)
     153              :         {
     154              :             // encoded value is too big to represent a correct chunk of size 1, 2 or 3 bytes
     155            3 :             return CHIP_ERROR_INVALID_ARGUMENT;
     156              :         }
     157              :     }
     158           32 :     return CHIP_NO_ERROR;
     159              : }
     160              : 
     161              : } // namespace chip
        

Generated by: LCOV version 2.0-1