Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/basecode.cpp
Line
Count
Source (jump to first uncovered line)
1
// basecode.cpp - originally written and placed in the public domain by Wei Dai
2
3
#include "pch.h"
4
#include "config.h"
5
6
#ifndef CRYPTOPP_IMPORTS
7
8
#include "basecode.h"
9
#include "fltrimpl.h"
10
#include <ctype.h>
11
12
NAMESPACE_BEGIN(CryptoPP)
13
14
void BaseN_Encoder::IsolatedInitialize(const NameValuePairs &parameters)
15
0
{
16
0
  parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet);
17
18
0
  parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar);
19
0
  if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
20
0
    throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive");
21
22
0
  byte padding;
23
0
  bool pad;
24
0
  if (parameters.GetValue(Name::PaddingByte(), padding))
25
0
    pad = parameters.GetValueWithDefault(Name::Pad(), true);
26
0
  else
27
0
    pad = false;
28
0
  m_padding = pad ? padding : -1;
29
30
0
  m_bytePos = m_bitPos = 0;
31
32
0
  int i = 8;
33
0
  while (i%m_bitsPerChar != 0)
34
0
    i += 8;
35
0
  m_outputBlockSize = i/m_bitsPerChar;
36
37
0
  m_outBuf.New(m_outputBlockSize);
38
0
}
39
40
size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
41
0
{
42
0
  FILTER_BEGIN;
43
0
  while (m_inputPosition < length)
44
0
  {
45
0
    if (m_bytePos == 0)
46
0
      std::memset(m_outBuf, 0, m_outputBlockSize);
47
48
0
    {
49
0
    unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8;
50
0
    while (true)
51
0
    {
52
0
      CRYPTOPP_ASSERT(m_bitsPerChar-m_bitPos >= 0);
53
0
      unsigned int bitsLeftInTarget = (unsigned int)(m_bitsPerChar-m_bitPos);
54
0
      m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget);
55
0
      if (bitsLeftInSource >= bitsLeftInTarget)
56
0
      {
57
0
        m_bitPos = 0;
58
0
        ++m_bytePos;
59
0
        bitsLeftInSource -= bitsLeftInTarget;
60
0
        if (bitsLeftInSource == 0)
61
0
          break;
62
0
        b <<= bitsLeftInTarget;
63
0
        b &= 0xff;
64
0
      }
65
0
      else
66
0
      {
67
0
        m_bitPos += bitsLeftInSource;
68
0
        break;
69
0
      }
70
0
    }
71
0
    }
72
73
0
    CRYPTOPP_ASSERT(m_bytePos <= m_outputBlockSize);
74
0
    if (m_bytePos == m_outputBlockSize)
75
0
    {
76
0
      int i;
77
0
      for (i=0; i<m_bytePos; i++)
78
0
      {
79
0
        CRYPTOPP_ASSERT(m_outBuf[i] < (1 << m_bitsPerChar));
80
0
        m_outBuf[i] = m_alphabet[m_outBuf[i]];
81
0
      }
82
0
      FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
83
84
0
      m_bytePos = m_bitPos = 0;
85
0
    }
86
0
  }
87
0
  if (messageEnd)
88
0
  {
89
0
    if (m_bitPos > 0)
90
0
      ++m_bytePos;
91
92
0
    int i;
93
0
    for (i=0; i<m_bytePos; i++)
94
0
      m_outBuf[i] = m_alphabet[m_outBuf[i]];
95
96
0
    if (m_padding != -1 && m_bytePos > 0)
97
0
    {
98
0
      std::memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos);
99
0
      m_bytePos = m_outputBlockSize;
100
0
    }
101
0
    FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
102
0
    m_bytePos = m_bitPos = 0;
103
0
  }
104
0
  FILTER_END_NO_MESSAGE_END;
105
0
}
106
107
void BaseN_Decoder::IsolatedInitialize(const NameValuePairs &parameters)
108
135k
{
109
135k
  parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup);
110
111
135k
  parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar);
112
135k
  if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
113
0
    throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive");
114
115
135k
  m_bytePos = m_bitPos = 0;
116
117
135k
  int i = m_bitsPerChar;
118
271k
  while (i%8 != 0)
119
135k
    i += m_bitsPerChar;
120
135k
  m_outputBlockSize = i/8;
121
122
135k
  m_outBuf.New(m_outputBlockSize);
123
135k
}
124
125
size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
126
407k
{
127
407k
  FILTER_BEGIN;
128
10.2M
  while (m_inputPosition < length)
129
9.82M
  {
130
9.82M
    unsigned int value;
131
9.82M
    value = m_lookup[begin[m_inputPosition++]];
132
9.82M
    if (value >= 256)
133
0
      continue;
134
135
9.82M
    if (m_bytePos == 0 && m_bitPos == 0)
136
4.91M
      std::memset(m_outBuf, 0, m_outputBlockSize);
137
138
9.82M
    {
139
9.82M
      int newBitPos = m_bitPos + m_bitsPerChar;
140
9.82M
      if (newBitPos <= 8)
141
9.82M
        m_outBuf[m_bytePos] |= value << (8-newBitPos);
142
0
      else
143
0
      {
144
0
        m_outBuf[m_bytePos] |= value >> (newBitPos-8);
145
0
        m_outBuf[m_bytePos+1] |= value << (16-newBitPos);
146
0
      }
147
148
9.82M
      m_bitPos = newBitPos;
149
14.7M
      while (m_bitPos >= 8)
150
4.91M
      {
151
4.91M
        m_bitPos -= 8;
152
4.91M
        ++m_bytePos;
153
4.91M
      }
154
9.82M
    }
155
156
9.82M
    if (m_bytePos == m_outputBlockSize)
157
4.91M
    {
158
4.91M
      FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
159
4.91M
      m_bytePos = m_bitPos = 0;
160
4.91M
    }
161
9.82M
  }
162
407k
  if (messageEnd)
163
135k
  {
164
135k
    FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
165
135k
    m_bytePos = m_bitPos = 0;
166
135k
  }
167
407k
  FILTER_END_NO_MESSAGE_END;
168
0
}
169
170
void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
171
0
{
172
0
  std::fill(lookup, lookup+256, -1);
173
174
0
  for (unsigned int i=0; i<base; i++)
175
0
  {
176
    // Debug asserts for 'lookup[alphabet[i]] == -1' removed because the self tests
177
    // have unusual tests that try to break the encoders and decoders. Tests include
178
    // a string of the same characters. I.,e., a string of stars like '********...'.
179
0
    if (caseInsensitive && isalpha(alphabet[i]))
180
0
    {
181
0
      lookup[toupper(alphabet[i])] = i;
182
0
      lookup[tolower(alphabet[i])] = i;
183
0
    }
184
0
    else
185
0
    {
186
0
      lookup[alphabet[i]] = i;
187
0
    }
188
0
  }
189
0
}
190
191
void Grouper::IsolatedInitialize(const NameValuePairs &parameters)
192
0
{
193
0
  m_groupSize = parameters.GetIntValueWithDefault(Name::GroupSize(), 0);
194
0
  ConstByteArrayParameter separator, terminator;
195
0
  if (m_groupSize)
196
0
    parameters.GetRequiredParameter("Grouper", Name::Separator(), separator);
197
0
  else
198
0
    parameters.GetValue(Name::Separator(), separator);
199
0
  parameters.GetValue(Name::Terminator(), terminator);
200
201
0
  m_separator.Assign(separator.begin(), separator.size());
202
0
  m_terminator.Assign(terminator.begin(), terminator.size());
203
0
  m_counter = 0;
204
0
}
205
206
size_t Grouper::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
207
0
{
208
0
  FILTER_BEGIN;
209
0
  if (m_groupSize)
210
0
  {
211
0
    while (m_inputPosition < length)
212
0
    {
213
0
      if (m_counter == m_groupSize)
214
0
      {
215
0
        FILTER_OUTPUT(1, m_separator, m_separator.size(), 0);
216
0
        m_counter = 0;
217
0
      }
218
219
0
      size_t len;
220
0
      FILTER_OUTPUT2(2, (len = STDMIN(length-m_inputPosition, m_groupSize-m_counter)),
221
0
        begin+m_inputPosition, len, 0);
222
0
      m_inputPosition += len;
223
0
      m_counter += len;
224
0
    }
225
0
  }
226
0
  else
227
0
    FILTER_OUTPUT(3, begin, length, 0);
228
229
0
  if (messageEnd)
230
0
  {
231
0
    FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd);
232
0
    m_counter = 0;
233
0
  }
234
0
  FILTER_END_NO_MESSAGE_END
235
0
}
236
237
NAMESPACE_END
238
239
#endif