/** * Decodes a BASE64 encoded data block. Returns True if string has been * successfully decoded, or False if it cannot be decoded (or memory * allocation fails). Does not destroy the original contents of the * buffer */ STATIC Bool BASE64_InternalDecode(Base64Decode * decode) { /* remember the original length so that we can undo the damage */ Buffer* out = decode->out; size_t origLen = (out ? BUFFER_Size(out) : 0); /* read the bulk of the data */ int n; Bool ok = True; I8u chunk[4]; while ((n = BASE64_ReadChunk(decode, chunk)) == 4) { if (out) { if (!BUFFER_PutByte(out,BASE64_DECODE_1(chunk[0],chunk[1])) || !BUFFER_PutByte(out,BASE64_DECODE_2(chunk[1],chunk[2])) || !BUFFER_PutByte(out,BASE64_DECODE_3(chunk[2],chunk[3]))) { /* out of memory */ ok = False; break; } } } /* deal with the trailer */ if (out && ok) { switch (n) { case 0: break; case 1: /* premature end of BASE64 stream */ decode->flags |= FLAG_ERROR; break; case 2: if (!BUFFER_PutByte(out,BASE64_DECODE_1(chunk[0],chunk[1]))) { /* out of memory */ ok = False; } break; case 3: if (!BUFFER_PutByte(out,BASE64_DECODE_1(chunk[0],chunk[1])) || !BUFFER_PutByte(out,BASE64_DECODE_2(chunk[1],chunk[2]))) { /* out of memory */ ok = False; } break; case 4: if (!BUFFER_PutByte(out,BASE64_DECODE_1(chunk[0],chunk[1])) || !BUFFER_PutByte(out,BASE64_DECODE_2(chunk[1],chunk[2])) || !BUFFER_PutByte(out,BASE64_DECODE_3(chunk[2],chunk[3]))) { /* out of memory */ ok = False; } break; } } /* return True if the input was a valid BASE64 sequence */ if ((decode->flags & FLAG_ERROR) || !ok) { if (out) { BUFFER_Unput(out,BUFFER_Size(out)-origLen); ASSERT(BUFFER_Size(out) == (int)origLen); } return False; } else { return True; } }
/** * Decodes a BASE32 encoded data block. Returns True if string has been * successfully decoded, or False if it cannot be decoded (or memory * allocation fails). Does not destroy the original contents of the * buffer */ STATIC Bool BASE32_InternalDecode(Base32Decode * decode) { /* remember the original length so that we can undo the damage */ Buffer * out = decode->out; int origLen = (out ? BUFFER_Size(out) : 0); /* read the bulk of the data */ int n; Bool ok = True; I8u b[DECODE_CHUNK_SIZE]; while ((n = BASE32_ReadChunk(decode, b)) == DECODE_CHUNK_SIZE) { if (out) { if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1])) || !BUFFER_PutByte(out,BASE32_DECODE_2(b[1],b[2],b[3])) || !BUFFER_PutByte(out,BASE32_DECODE_3(b[3],b[4])) || !BUFFER_PutByte(out,BASE32_DECODE_4(b[4],b[5],b[6])) || !BUFFER_PutByte(out,BASE32_DECODE_5(b[6],b[7]))) { /* out of memory */ ok = False; break; } } } /* * +--- octet 0 ---+--- octet 1 ---+--- octet 2 ---+ * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| * +---------+-----+---+---------+-+-------+-------+ * |4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 * +-0.index-+-1.index-+-2.index-+-3.index-+-4.index * * +--- octet 3 ---+--- octet 4 ---+ * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| * +-+---------+---+-----+---------+ * 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 0| * --+-5.index-+-6.index-+-7.index-+ */ /* deal with the trailer */ if (out && ok) { switch (n) { case 0: break; case 1: case 3: case 6: /* incorrect trailer */ decode->flags |= FLAG_ERROR; break; case 2: if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1]))) { /* out of memory */ ok = False; } break; case 4: if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1])) || !BUFFER_PutByte(out,BASE32_DECODE_2(b[1],b[2],b[3]))) { /* out of memory */ ok = False; return False; } break; case 5: if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1])) || !BUFFER_PutByte(out,BASE32_DECODE_2(b[1],b[2],b[3])) || !BUFFER_PutByte(out,BASE32_DECODE_3(b[3],b[4]))) { /* out of memory */ ok = False; return False; } break; case 7: if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1])) || !BUFFER_PutByte(out,BASE32_DECODE_2(b[1],b[2],b[3])) || !BUFFER_PutByte(out,BASE32_DECODE_3(b[3],b[4])) || !BUFFER_PutByte(out,BASE32_DECODE_4(b[4],b[5],b[6]))) { /* out of memory */ ok = False; return False; } break; } } /* return True if the input was a valid BASE32 sequence */ if ((decode->flags & FLAG_ERROR) || !ok) { if (out) { BUFFER_Unput(out,BUFFER_Size(out)-origLen); ASSERT(BUFFER_Size(out) == origLen); } return False; } else { return True; } }