comparison src/util.c @ 11127:719779387f96

[gaim-migrate @ 13183] Change the base16 and base64 functions to use better data types, and make appropriate changes to other parts of the Gaim code to get rid of a few warnings and hopefully make things more correct. In other news, why is CVS HEAD crashing for me on exit? committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Tue, 19 Jul 2005 05:15:45 +0000
parents a8a7730db73c
children a4611130e3eb
comparison
equal deleted inserted replaced
11126:2a3568cbd8a6 11127:719779387f96
65 static char home_dir[MAXPATHLEN]; 65 static char home_dir[MAXPATHLEN];
66 66
67 /************************************************************************** 67 /**************************************************************************
68 * Base16 Functions 68 * Base16 Functions
69 **************************************************************************/ 69 **************************************************************************/
70 unsigned char * 70 gchar *
71 gaim_base16_encode(const unsigned char *data, int length) 71 gaim_base16_encode(const guint8 *data, gsize len)
72 { 72 {
73 int i; 73 int i;
74 unsigned char *ascii = NULL; 74 gchar *ascii = NULL;
75 75
76 g_return_val_if_fail(data != NULL, NULL); 76 g_return_val_if_fail(data != NULL, NULL);
77 g_return_val_if_fail(length > 0, NULL); 77 g_return_val_if_fail(len > 0, NULL);
78 78
79 ascii = g_malloc(length * 2 + 1); 79 ascii = g_malloc(len * 2 + 1);
80 80
81 for (i = 0; i < length; i++) 81 for (i = 0; i < len; i++)
82 snprintf(&ascii[i * 2], 3, "%02hhx", data[i]); 82 snprintf(&ascii[i * 2], 3, "%02hhx", data[i]);
83 83
84 return ascii; 84 return ascii;
85 } 85 }
86 86
87 int 87 guint8 *
88 gaim_base16_decode(const char *ascii, unsigned char **raw) 88 gaim_base16_decode(const char *str, gsize *ret_len)
89 { 89 {
90 int len, i, accumulator = 0; 90 int len, i, accumulator = 0;
91 unsigned char *data; 91 guint8 *data;
92 92
93 g_return_val_if_fail(ascii != NULL, 0); 93 g_return_val_if_fail(str != NULL, NULL);
94 94
95 len = strlen(ascii); 95 len = strlen(str);
96 96
97 g_return_val_if_fail(strlen(ascii) > 0, 0); 97 g_return_val_if_fail(strlen(str) > 0, 0);
98 g_return_val_if_fail(len % 2 > 0, 0); 98 g_return_val_if_fail(len % 2 > 0, 0);
99 99
100 data = g_malloc(len / 2); 100 data = g_malloc(len / 2);
101 101
102 for (i = 0; i < len; i++) 102 for (i = 0; i < len; i++)
104 if ((i % 2) == 0) 104 if ((i % 2) == 0)
105 accumulator = 0; 105 accumulator = 0;
106 else 106 else
107 accumulator <<= 4; 107 accumulator <<= 4;
108 108
109 if (isdigit(ascii[i])) 109 if (isdigit(str[i]))
110 accumulator |= ascii[i] - 48; 110 accumulator |= str[i] - 48;
111 else 111 else
112 { 112 {
113 switch(ascii[i]) 113 switch(str[i])
114 { 114 {
115 case 'a': case 'A': accumulator |= 10; break; 115 case 'a': case 'A': accumulator |= 10; break;
116 case 'b': case 'B': accumulator |= 11; break; 116 case 'b': case 'B': accumulator |= 11; break;
117 case 'c': case 'C': accumulator |= 12; break; 117 case 'c': case 'C': accumulator |= 12; break;
118 case 'd': case 'D': accumulator |= 13; break; 118 case 'd': case 'D': accumulator |= 13; break;
123 123
124 if (i % 2) 124 if (i % 2)
125 data[(i - 1) / 2] = accumulator; 125 data[(i - 1) / 2] = accumulator;
126 } 126 }
127 127
128 *raw = data; 128 if (ret_len != NULL)
129 129 *ret_len = len / 2;
130 return (len / 2); 130
131 return data;
131 } 132 }
132 133
133 /************************************************************************** 134 /**************************************************************************
134 * Base64 Functions 135 * Base64 Functions
135 **************************************************************************/ 136 **************************************************************************/
138 "0123456789+/"; 139 "0123456789+/";
139 140
140 static const char xdigits[] = 141 static const char xdigits[] =
141 "0123456789abcdef"; 142 "0123456789abcdef";
142 143
143 unsigned char * 144 gchar *
144 gaim_base64_encode(const unsigned char *in, size_t inlen) 145 gaim_base64_encode(const guint8 *data, gsize len)
145 { 146 {
146 char *out, *rv; 147 char *out, *rv;
147 148
148 g_return_val_if_fail(in != NULL, NULL); 149 g_return_val_if_fail(data != NULL, NULL);
149 g_return_val_if_fail(inlen > 0, NULL); 150 g_return_val_if_fail(len > 0, NULL);
150 151
151 rv = out = g_malloc(((inlen/3)+1)*4 + 1); 152 rv = out = g_malloc(((len/3)+1)*4 + 1);
152 153
153 for (; inlen >= 3; inlen -= 3) 154 for (; len >= 3; len -= 3)
154 { 155 {
155 *out++ = alphabet[in[0] >> 2]; 156 *out++ = alphabet[data[0] >> 2];
156 *out++ = alphabet[((in[0] << 4) & 0x30) | (in[1] >> 4)]; 157 *out++ = alphabet[((data[0] << 4) & 0x30) | (data[1] >> 4)];
157 *out++ = alphabet[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; 158 *out++ = alphabet[((data[1] << 2) & 0x3c) | (data[2] >> 6)];
158 *out++ = alphabet[in[2] & 0x3f]; 159 *out++ = alphabet[data[2] & 0x3f];
159 in += 3; 160 data += 3;
160 } 161 }
161 162
162 if (inlen > 0) 163 if (len > 0)
163 { 164 {
164 unsigned char fragment; 165 unsigned char fragment;
165 166
166 *out++ = alphabet[in[0] >> 2]; 167 *out++ = alphabet[data[0] >> 2];
167 fragment = (in[0] << 4) & 0x30; 168 fragment = (data[0] << 4) & 0x30;
168 169
169 if (inlen > 1) 170 if (len > 1)
170 fragment |= in[1] >> 4; 171 fragment |= data[1] >> 4;
171 172
172 *out++ = alphabet[fragment]; 173 *out++ = alphabet[fragment];
173 *out++ = (inlen < 2) ? '=' : alphabet[(in[1] << 2) & 0x3c]; 174 *out++ = (len < 2) ? '=' : alphabet[(data[1] << 2) & 0x3c];
174 *out++ = '='; 175 *out++ = '=';
175 } 176 }
176 177
177 *out = '\0'; 178 *out = '\0';
178 179
179 return rv; 180 return rv;
180 } 181 }
181 182
182 void 183 guint8 *
183 gaim_base64_decode(const char *text, char **data, int *size) 184 gaim_base64_decode(const char *str, gsize *ret_len)
184 { 185 {
185 char *out = NULL; 186 guint8 *out = NULL;
186 char tmp = 0; 187 char tmp = 0;
187 const char *c; 188 const char *c;
188 gint32 tmp2 = 0; 189 gint32 tmp2 = 0;
189 int len = 0, n = 0; 190 int len = 0, n = 0;
190 191
191 g_return_if_fail(text != NULL); 192 g_return_val_if_fail(str != NULL, NULL);
192 g_return_if_fail(data != NULL); 193
193 194 c = str;
194 c = text;
195 195
196 while (*c) { 196 while (*c) {
197 if (*c >= 'A' && *c <= 'Z') { 197 if (*c >= 'A' && *c <= 'Z') {
198 tmp = *c - 'A'; 198 tmp = *c - 'A';
199 } else if (*c >= 'a' && *c <= 'z') { 199 } else if (*c >= 'a' && *c <= 'z') {
208 c++; 208 c++;
209 continue; 209 continue;
210 } else if (*c == '=') { 210 } else if (*c == '=') {
211 if (n == 3) { 211 if (n == 3) {
212 out = g_realloc(out, len + 2); 212 out = g_realloc(out, len + 2);
213 out[len] = (char)(tmp2 >> 10) & 0xff; 213 out[len] = (guint8)(tmp2 >> 10) & 0xff;
214 len++; 214 len++;
215 out[len] = (char)(tmp2 >> 2) & 0xff; 215 out[len] = (guint8)(tmp2 >> 2) & 0xff;
216 len++; 216 len++;
217 } else if (n == 2) { 217 } else if (n == 2) {
218 out = g_realloc(out, len + 1); 218 out = g_realloc(out, len + 1);
219 out[len] = (char)(tmp2 >> 4) & 0xff; 219 out[len] = (guint8)(tmp2 >> 4) & 0xff;
220 len++; 220 len++;
221 } 221 }
222 break; 222 break;
223 } 223 }
224 tmp2 = ((tmp2 << 6) | (tmp & 0xff)); 224 tmp2 = ((tmp2 << 6) | (tmp & 0xff));
225 n++; 225 n++;
226 if (n == 4) { 226 if (n == 4) {
227 out = g_realloc(out, len + 3); 227 out = g_realloc(out, len + 3);
228 out[len] = (char)((tmp2 >> 16) & 0xff); 228 out[len] = (guint8)((tmp2 >> 16) & 0xff);
229 len++; 229 len++;
230 out[len] = (char)((tmp2 >> 8) & 0xff); 230 out[len] = (guint8)((tmp2 >> 8) & 0xff);
231 len++; 231 len++;
232 out[len] = (char)(tmp2 & 0xff); 232 out[len] = (guint8)(tmp2 & 0xff);
233 len++; 233 len++;
234 tmp2 = 0; 234 tmp2 = 0;
235 n = 0; 235 n = 0;
236 } 236 }
237 c++; 237 c++;
238 } 238 }
239 239
240 out = g_realloc(out, len + 1); 240 out = g_realloc(out, len + 1);
241 out[len] = 0; 241 out[len] = 0;
242 242
243 *data = out; 243 if (ret_len != NULL)
244 244 *ret_len = len;
245 if (size) 245
246 *size = len; 246 return out;
247 } 247 }
248 248
249 /************************************************************************** 249 /**************************************************************************
250 * Quoted Printable Functions (see RFC 1341) 250 * Quoted Printable Functions (see RFC 1341)
251 **************************************************************************/ 251 **************************************************************************/
408 case state_question4: 408 case state_question4:
409 if (*cur == '=') { /* Got the whole encoded-word */ 409 if (*cur == '=') { /* Got the whole encoded-word */
410 char *charset = g_strndup(charset0, encoding0 - charset0 - 1); 410 char *charset = g_strndup(charset0, encoding0 - charset0 - 1);
411 char *encoding = g_strndup(encoding0, encoded_text0 - encoding0 - 1); 411 char *encoding = g_strndup(encoding0, encoded_text0 - encoding0 - 1);
412 char *encoded_text = g_strndup(encoded_text0, cur - encoded_text0 - 1); 412 char *encoded_text = g_strndup(encoded_text0, cur - encoded_text0 - 1);
413 char *decoded = NULL; 413 guint8 *decoded = NULL;
414 int dec_len; 414 gsize dec_len;
415 if (g_ascii_strcasecmp(encoding, "Q") == 0) 415 if (g_ascii_strcasecmp(encoding, "Q") == 0)
416 gaim_quotedp_decode(encoded_text, &decoded, &dec_len); 416 gaim_quotedp_decode(encoded_text, &decoded, &dec_len);
417 else if (g_ascii_strcasecmp(encoding, "B") == 0) 417 else if (g_ascii_strcasecmp(encoding, "B") == 0)
418 gaim_base64_decode(encoded_text, &decoded, &dec_len); 418 decoded = gaim_base64_decode(encoded_text, &dec_len);
419 else 419 else
420 decoded = NULL; 420 decoded = NULL;
421 if (decoded) { 421 if (decoded) {
422 gsize len; 422 gsize len;
423 char *converted = g_convert(decoded, dec_len, "utf-8", charset, NULL, &len, NULL); 423 char *converted = g_convert(decoded, dec_len, "utf-8", charset, NULL, &len, NULL);