File Coverage

bson/b64_ntop.h
Criterion Covered Total %
statement 0 43 0.0
branch 0 28 0.0
condition n/a
subroutine n/a
pod n/a
total 0 71 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 1996, 1998 by Internet Software Consortium.
3             *
4             * Permission to use, copy, modify, and distribute this software for any
5             * purpose with or without fee is hereby granted, provided that the above
6             * copyright notice and this permission notice appear in all copies.
7             *
8             * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9             * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10             * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11             * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12             * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13             * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14             * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15             * SOFTWARE.
16             */
17              
18             /*
19             * Portions Copyright (c) 1995 by International Business Machines, Inc.
20             *
21             * International Business Machines, Inc. (hereinafter called IBM) grants
22             * permission under its copyrights to use, copy, modify, and distribute this
23             * Software with or without fee, provided that the above copyright notice and
24             * all paragraphs of this notice appear in all copies, and that the name of IBM
25             * not be used in connection with the marketing of any product incorporating
26             * the Software or modifications thereof, without specific, written prior
27             * permission.
28             *
29             * To the extent it has a right to do so, IBM grants an immunity from suit
30             * under its patents, if any, for the use, sale or manufacture of products to
31             * the extent that such products are used for performing Domain Name System
32             * dynamic updates in TCP/IP networks by means of the Software. No immunity is
33             * granted for any product per se or for any other function of any product.
34             *
35             * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
36             * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
37             * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
38             * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
39             * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
40             * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
41             */
42              
43             #include "bson-compat.h"
44             #include "bson-macros.h"
45             #include "bson-types.h"
46              
47             #define Assert(Cond) if (!(Cond)) abort ()
48              
49             static const char Base64[] =
50             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
51             static const char Pad64 = '=';
52              
53             /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
54             * The following encoding technique is taken from RFC 1521 by Borenstein
55             * and Freed. It is reproduced here in a slightly edited form for
56             * convenience.
57             *
58             * A 65-character subset of US-ASCII is used, enabling 6 bits to be
59             * represented per printable character. (The extra 65th character, "=",
60             * is used to signify a special processing function.)
61             *
62             * The encoding process represents 24-bit groups of input bits as output
63             * strings of 4 encoded characters. Proceeding from left to right, a
64             * 24-bit input group is formed by concatenating 3 8-bit input groups.
65             * These 24 bits are then treated as 4 concatenated 6-bit groups, each
66             * of which is translated into a single digit in the base64 alphabet.
67             *
68             * Each 6-bit group is used as an index into an array of 64 printable
69             * characters. The character referenced by the index is placed in the
70             * output string.
71             *
72             * Table 1: The Base64 Alphabet
73             *
74             * Value Encoding Value Encoding Value Encoding Value Encoding
75             * 0 A 17 R 34 i 51 z
76             * 1 B 18 S 35 j 52 0
77             * 2 C 19 T 36 k 53 1
78             * 3 D 20 U 37 l 54 2
79             * 4 E 21 V 38 m 55 3
80             * 5 F 22 W 39 n 56 4
81             * 6 G 23 X 40 o 57 5
82             * 7 H 24 Y 41 p 58 6
83             * 8 I 25 Z 42 q 59 7
84             * 9 J 26 a 43 r 60 8
85             * 10 K 27 b 44 s 61 9
86             * 11 L 28 c 45 t 62 +
87             * 12 M 29 d 46 u 63 /
88             * 13 N 30 e 47 v
89             * 14 O 31 f 48 w (pad) =
90             * 15 P 32 g 49 x
91             * 16 Q 33 h 50 y
92             *
93             * Special processing is performed if fewer than 24 bits are available
94             * at the end of the data being encoded. A full encoding quantum is
95             * always completed at the end of a quantity. When fewer than 24 input
96             * bits are available in an input group, zero bits are added (on the
97             * right) to form an integral number of 6-bit groups. Padding at the
98             * end of the data is performed using the '=' character.
99             *
100             * Since all base64 input is an integral number of octets, only the
101             * following cases can arise:
102             *
103             * (1) the final quantum of encoding input is an integral
104             * multiple of 24 bits; here, the final unit of encoded
105             * output will be an integral multiple of 4 characters
106             * with no "=" padding,
107             * (2) the final quantum of encoding input is exactly 8 bits;
108             * here, the final unit of encoded output will be two
109             * characters followed by two "=" padding characters, or
110             * (3) the final quantum of encoding input is exactly 16 bits;
111             * here, the final unit of encoded output will be three
112             * characters followed by one "=" padding character.
113             */
114              
115             static ssize_t
116 0           b64_ntop (uint8_t const *src,
117             size_t srclength,
118             char *target,
119             size_t targsize)
120             {
121 0           size_t datalength = 0;
122             uint8_t input[3];
123             uint8_t output[4];
124             size_t i;
125              
126 0 0         while (2 < srclength) {
127 0           input[0] = *src++;
128 0           input[1] = *src++;
129 0           input[2] = *src++;
130 0           srclength -= 3;
131              
132 0           output[0] = input[0] >> 2;
133 0           output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
134 0           output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
135 0           output[3] = input[2] & 0x3f;
136 0 0         Assert (output[0] < 64);
137 0 0         Assert (output[1] < 64);
138 0 0         Assert (output[2] < 64);
139 0 0         Assert (output[3] < 64);
140              
141 0 0         if (datalength + 4 > targsize) {
142 0           return -1;
143             }
144 0           target[datalength++] = Base64[output[0]];
145 0           target[datalength++] = Base64[output[1]];
146 0           target[datalength++] = Base64[output[2]];
147 0           target[datalength++] = Base64[output[3]];
148             }
149              
150             /* Now we worry about padding. */
151 0 0         if (0 != srclength) {
152             /* Get what's left. */
153 0           input[0] = input[1] = input[2] = '\0';
154              
155 0 0         for (i = 0; i < srclength; i++) {
156 0           input[i] = *src++;
157             }
158 0           output[0] = input[0] >> 2;
159 0           output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
160 0           output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
161 0 0         Assert (output[0] < 64);
162 0 0         Assert (output[1] < 64);
163 0 0         Assert (output[2] < 64);
164              
165 0 0         if (datalength + 4 > targsize) {
166 0           return -1;
167             }
168 0           target[datalength++] = Base64[output[0]];
169 0           target[datalength++] = Base64[output[1]];
170              
171 0 0         if (srclength == 1) {
172 0           target[datalength++] = Pad64;
173             } else{
174 0           target[datalength++] = Base64[output[2]];
175             }
176 0           target[datalength++] = Pad64;
177             }
178              
179 0 0         if (datalength >= targsize) {
180 0           return -1;
181             }
182 0           target[datalength] = '\0'; /* Returned value doesn't count \0. */
183 0           return datalength;
184             }