@@ -56,6 +56,12 @@ Return Values:
5656 if (cchEncodedStringSize == 0 && pszEncodedString == nullptr ) {
5757 return ERROR_SUCCESS;
5858 }
59+ else if (pszEncodedString == nullptr )
60+ {
61+ return ERROR_INVALID_PARAMETER;
62+ }
63+
64+ *pszEncodedString = 0 ;
5965
6066 if (cchEncodedStringSize < cchEncoded) {
6167 // Given buffer is too small to hold encoded string.
@@ -66,8 +72,16 @@ Return Values:
6672 ib = ich = 0 ;
6773 while (ib < cbDecodedBufferSize) {
6874 b0 = pbDecodedBuffer[ib++];
69- b1 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0 ;
70- b2 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0 ;
75+ b1 = 0 ;
76+ b2 = 0 ;
77+ if (ib < cbDecodedBufferSize)
78+ {
79+ b1 = pbDecodedBuffer[ib++];
80+ }
81+ if (ib < cbDecodedBufferSize)
82+ {
83+ b2 = pbDecodedBuffer[ib++];
84+ }
7185
7286 //
7387 // The checks below for buffer overflow seems redundant to me.
@@ -126,122 +140,6 @@ Return Values:
126140}
127141
128142
129- DWORD
130- Base64Decode (
131- __in PCWSTR pszEncodedString,
132- __out_opt VOID * pDecodeBuffer,
133- __in DWORD cbDecodeBufferSize,
134- __out_opt DWORD * pcbDecoded
135- )
136- /* ++
137-
138- Routine Description:
139-
140- Decode a base64-encoded string.
141-
142- Arguments:
143-
144- pszEncodedString (IN) - base64-encoded string to decode.
145- cbDecodeBufferSize (IN) - size in bytes of the decode buffer.
146- pbDecodeBuffer (OUT) - holds the decoded data.
147- pcbDecoded (OUT) - number of data bytes in the decoded data (if success or
148- STATUS_BUFFER_TOO_SMALL).
149-
150- Return Values:
151-
152- 0 - success.
153- E_OUTOFMEMORY
154- E_INVALIDARG
155-
156- --*/
157- {
158- constexpr auto NA = (255 );
159- #define DECODE (x ) (((ULONG)(x) < sizeof (rgbDecodeTable)) ? rgbDecodeTable[x] : NA)
160-
161- static BYTE rgbDecodeTable[128 ] = {
162- NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 0-15
163- NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 16-31
164- NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62 , NA, NA, NA, 63 , // 32-47
165- 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , NA, NA, NA, 0 , NA, NA, // 48-63
166- NA, 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , // 64-79
167- 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , NA, NA, NA, NA, NA, // 80-95
168- NA, 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , // 96-111
169- 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , NA, NA, NA, NA, NA, // 112-127
170- };
171-
172- DWORD cbDecoded;
173- DWORD cchEncodedSize;
174- DWORD ich;
175- DWORD ib;
176- BYTE b0, b1, b2, b3;
177- BYTE * pbDecodeBuffer = (BYTE *) pDecodeBuffer;
178-
179- cchEncodedSize = (DWORD)wcslen (pszEncodedString);
180- if (nullptr != pcbDecoded) {
181- *pcbDecoded = 0 ;
182- }
183-
184- if ((0 == cchEncodedSize) || (0 != (cchEncodedSize % 4 ))) {
185- // Input string is not sized correctly to be base64.
186- return ERROR_INVALID_PARAMETER;
187- }
188-
189- // Calculate decoded buffer size.
190- cbDecoded = (cchEncodedSize + 3 ) / 4 * 3 ;
191- if (pszEncodedString[cchEncodedSize-1 ] == ' =' ) {
192- if (pszEncodedString[cchEncodedSize-2 ] == ' =' ) {
193- // Only one data byte is encoded in the last cluster.
194- cbDecoded -= 2 ;
195- }
196- else {
197- // Only two data bytes are encoded in the last cluster.
198- cbDecoded -= 1 ;
199- }
200- }
201-
202- if (nullptr != pcbDecoded) {
203- *pcbDecoded = cbDecoded;
204- }
205-
206- if (cbDecodeBufferSize == 0 && pDecodeBuffer == nullptr ) {
207- return ERROR_SUCCESS;
208- }
209-
210- if (cbDecoded > cbDecodeBufferSize) {
211- // Supplied buffer is too small.
212- return ERROR_INSUFFICIENT_BUFFER;
213- }
214-
215- // Decode each four-byte cluster into the corresponding three data bytes.
216- ich = ib = 0 ;
217- while (ich < cchEncodedSize) {
218- b0 = DECODE (pszEncodedString[ich]); ich++;
219- b1 = DECODE (pszEncodedString[ich]); ich++;
220- b2 = DECODE (pszEncodedString[ich]); ich++;
221- b3 = DECODE (pszEncodedString[ich]); ich++;
222-
223- if ((NA == b0) || (NA == b1) || (NA == b2) || (NA == b3)) {
224- // Contents of input string are not base64.
225- return ERROR_INVALID_PARAMETER;
226- }
227-
228- pbDecodeBuffer[ib++] = (b0 << 2 ) | (b1 >> 4 );
229-
230- if (ib < cbDecoded) {
231- pbDecodeBuffer[ib++] = (b1 << 4 ) | (b2 >> 2 );
232-
233- if (ib < cbDecoded) {
234- pbDecodeBuffer[ib++] = (b2 << 6 ) | b3;
235- }
236- }
237- }
238-
239- DBG_ASSERT (ib == cbDecoded);
240-
241- return ERROR_SUCCESS;
242- }
243-
244-
245143DWORD
246144Base64Encode (
247145 __in_bcount (cbDecodedBufferSize) VOID * pDecodedBuffer,
@@ -295,6 +193,12 @@ Return Values:
295193 if (cchEncodedStringSize == 0 && pszEncodedString == nullptr ) {
296194 return ERROR_SUCCESS;
297195 }
196+ else if (pszEncodedString == nullptr )
197+ {
198+ return ERROR_INVALID_PARAMETER;
199+ }
200+
201+ *pszEncodedString = 0 ;
298202
299203 if (cchEncodedStringSize < cchEncoded) {
300204 // Given buffer is too small to hold encoded string.
@@ -305,8 +209,16 @@ Return Values:
305209 ib = ich = 0 ;
306210 while (ib < cbDecodedBufferSize) {
307211 b0 = pbDecodedBuffer[ib++];
308- b1 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0 ;
309- b2 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0 ;
212+ b1 = 0 ;
213+ b2 = 0 ;
214+ if (ib < cbDecodedBufferSize)
215+ {
216+ b1 = pbDecodedBuffer[ib++];
217+ }
218+ if (ib < cbDecodedBufferSize)
219+ {
220+ b2 = pbDecodedBuffer[ib++];
221+ }
310222
311223 //
312224 // The checks below for buffer overflow seems redundant to me.
@@ -363,120 +275,3 @@ Return Values:
363275
364276 return ERROR_SUCCESS;
365277}
366-
367-
368- DWORD
369- Base64Decode (
370- __in PCSTR pszEncodedString,
371- __out_opt VOID * pDecodeBuffer,
372- __in DWORD cbDecodeBufferSize,
373- __out_opt DWORD * pcbDecoded
374- )
375- /* ++
376-
377- Routine Description:
378-
379- Decode a base64-encoded string.
380-
381- Arguments:
382-
383- pszEncodedString (IN) - base64-encoded string to decode.
384- cbDecodeBufferSize (IN) - size in bytes of the decode buffer.
385- pbDecodeBuffer (OUT) - holds the decoded data.
386- pcbDecoded (OUT) - number of data bytes in the decoded data (if success or
387- STATUS_BUFFER_TOO_SMALL).
388-
389- Return Values:
390-
391- 0 - success.
392- E_OUTOFMEMORY
393- E_INVALIDARG
394-
395- --*/
396- {
397- #define NA (255 )
398- #define DECODE (x ) (((ULONG)(x) < sizeof (rgbDecodeTable)) ? rgbDecodeTable[x] : NA)
399-
400- static BYTE rgbDecodeTable[128 ] = {
401- NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 0-15
402- NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 16-31
403- NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62 , NA, NA, NA, 63 , // 32-47
404- 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , NA, NA, NA, 0 , NA, NA, // 48-63
405- NA, 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , // 64-79
406- 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , NA, NA, NA, NA, NA, // 80-95
407- NA, 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , // 96-111
408- 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , NA, NA, NA, NA, NA, // 112-127
409- };
410-
411- DWORD cbDecoded;
412- DWORD cchEncodedSize;
413- DWORD ich;
414- DWORD ib;
415- BYTE b0, b1, b2, b3;
416- BYTE * pbDecodeBuffer = (BYTE *) pDecodeBuffer;
417-
418- cchEncodedSize = (DWORD)strlen (pszEncodedString);
419- if (nullptr != pcbDecoded) {
420- *pcbDecoded = 0 ;
421- }
422-
423- if ((0 == cchEncodedSize) || (0 != (cchEncodedSize % 4 ))) {
424- // Input string is not sized correctly to be base64.
425- return ERROR_INVALID_PARAMETER;
426- }
427-
428- // Calculate decoded buffer size.
429- cbDecoded = (cchEncodedSize + 3 ) / 4 * 3 ;
430- if (pszEncodedString[cchEncodedSize-1 ] == ' =' ) {
431- if (pszEncodedString[cchEncodedSize-2 ] == ' =' ) {
432- // Only one data byte is encoded in the last cluster.
433- cbDecoded -= 2 ;
434- }
435- else {
436- // Only two data bytes are encoded in the last cluster.
437- cbDecoded -= 1 ;
438- }
439- }
440-
441- if (nullptr != pcbDecoded) {
442- *pcbDecoded = cbDecoded;
443- }
444-
445- if (cbDecodeBufferSize == 0 && pDecodeBuffer == nullptr ) {
446- return ERROR_SUCCESS;
447- }
448-
449- if (cbDecoded > cbDecodeBufferSize) {
450- // Supplied buffer is too small.
451- return ERROR_INSUFFICIENT_BUFFER;
452- }
453-
454- // Decode each four-byte cluster into the corresponding three data bytes.
455- ich = ib = 0 ;
456- while (ich < cchEncodedSize) {
457- b0 = DECODE (pszEncodedString[ich]); ich++;
458- b1 = DECODE (pszEncodedString[ich]); ich++;
459- b2 = DECODE (pszEncodedString[ich]); ich++;
460- b3 = DECODE (pszEncodedString[ich]); ich++;
461-
462- if ((NA == b0) || (NA == b1) || (NA == b2) || (NA == b3)) {
463- // Contents of input string are not base64.
464- return ERROR_INVALID_PARAMETER;
465- }
466-
467- pbDecodeBuffer[ib++] = (b0 << 2 ) | (b1 >> 4 );
468-
469- if (ib < cbDecoded) {
470- pbDecodeBuffer[ib++] = (b1 << 4 ) | (b2 >> 2 );
471-
472- if (ib < cbDecoded) {
473- pbDecodeBuffer[ib++] = (b2 << 6 ) | b3;
474- }
475- }
476- }
477-
478- DBG_ASSERT (ib == cbDecoded);
479-
480- return ERROR_SUCCESS;
481- }
482-
0 commit comments