non-ASCII platforms.
Changelog
+Daniel (4 January 2007)
+- David McCreedy made changes to allow base64 encoding/decoding to work on
+ non-ASCII platforms.
+
Daniel (3 January 2007)
- Matt Witherspoon fixed the flaw which made libcurl 7.16.0 always store
downloaded data in two buffers, just to be able to deal with a special HTTP
o --limit-rate (CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE)
now work on windows again
o improved download performance by avoiding the unconditional "double copying"
+ o base64 encoding/decoding works on non-ASCII platforms
Other curl-related news:
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
+#include "urldata.h" /* for the SessionHandle definition */
+#include "easyif.h" /* for Curl_convert_... prototypes */
#include "base64.h"
#include "memory.h"
/* include memdebug.h last */
#include "memdebug.h"
+/* ---- Base64 Encoding/Decoding Table --- */
+static const char table64[]=
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void decodeQuantum(unsigned char *dest, const char *src)
{
unsigned int x = 0;
int i;
+ char *found;
+
for(i = 0; i < 4; i++) {
- if(src[i] >= 'A' && src[i] <= 'Z')
- x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);
- else if(src[i] >= 'a' && src[i] <= 'z')
- x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);
- else if(src[i] >= '0' && src[i] <= '9')
- x = (x << 6) + (unsigned int)(src[i] - '0' + 52);
- else if(src[i] == '+')
- x = (x << 6) + 62;
- else if(src[i] == '/')
- x = (x << 6) + 63;
+ if((found = strchr(table64, src[i])))
+ x = (x << 6) + (unsigned int)(found - table64);
else if(src[i] == '=')
x = (x << 6);
}
return rawlen;
}
-/* ---- Base64 Encoding --- */
-static const char table64[]=
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
/*
* Curl_base64_encode()
*
* went wrong, -1 is returned.
*
*/
-size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
+size_t Curl_base64_encode(struct SessionHandle *data,
+ const char *inp, size_t insize, char **outptr)
{
unsigned char ibuf[3];
unsigned char obuf[4];
int inputparts;
char *output;
char *base64data;
+#ifdef CURL_DOES_CONVERSIONS
+ char *convbuf;
+#endif
char *indata = (char *)inp;
if(NULL == output)
return 0;
+#ifdef CURL_DOES_CONVERSIONS
+ /*
+ * The base64 data needs to be created using the network encoding
+ * not the host encoding. And we can't change the actual input
+ * so we copy it to a buffer, translate it, and use that instead.
+ */
+ if(data) {
+ convbuf = (char*)malloc(insize);
+ if(!convbuf) {
+ return 0;
+ }
+ memcpy(convbuf, indata, insize);
+ if(CURLE_OK != Curl_convert_to_network(data, convbuf, insize)) {
+ free(convbuf);
+ return 0;
+ }
+ indata = convbuf; /* switch to the converted buffer */
+ }
+#else
+ (void)data;
+#endif
+
while(insize > 0) {
for (i = inputparts = 0; i < 3; i++) {
if(insize > 0) {
*output=0;
*outptr = base64data; /* make it return the actual data memory */
+#ifdef CURL_DOES_CONVERSIONS
+ if(data)
+ free(convbuf);
+#endif
return strlen(base64data); /* return the length of the new data */
}
/* ---- End of Base64 Encoding ---- */
size_t base64Len;
unsigned char *data;
int dataLen;
+ struct SessionHandle *handle = NULL;
+#ifdef CURL_DOES_CONVERSIONS
+ /* get a Curl handle so Curl_base64_encode can translate properly */
+ handle = curl_easy_init();
+ if(handle == NULL) {
+ fprintf(stderr, "Error: curl_easy_init failed\n");
+ return 0;
+ }
+#endif
data = (unsigned char *)suck(&dataLen);
- base64Len = Curl_base64_encode(data, dataLen, &base64);
+ base64Len = Curl_base64_encode(handle, data, dataLen, &base64);
fprintf(stderr, "%d\n", base64Len);
- fprintf(stdout, "%s", base64);
+ fprintf(stdout, "%s\n", base64);
free(base64); free(data);
+#ifdef CURL_DOES_CONVERSIONS
+ curl_easy_cleanup(handle);
+#endif
return 0;
}
#endif
unsigned char *data;
int dataLen;
int i, j;
+#ifdef CURL_DOES_CONVERSIONS
+ /* get a Curl handle so main can translate properly */
+ struct SessionHandle *handle = curl_easy_init();
+ if(handle == NULL) {
+ fprintf(stderr, "Error: curl_easy_init failed\n");
+ return 0;
+ }
+#endif
base64 = (char *)suck(&base64Len);
- data = (unsigned char *)malloc(base64Len * 3/4 + 8);
- dataLen = Curl_base64_decode(base64, data);
+ dataLen = Curl_base64_decode(base64, &data);
fprintf(stderr, "%d\n", dataLen);
printf(" | ");
for(j=0; j < 0x10; j++)
- if((j+i) < dataLen)
+ if((j+i) < dataLen) {
+#ifdef CURL_DOES_CONVERSIONS
+ if(CURLE_OK !=
+ Curl_convert_from_network(handle, &data[i+j], (size_t)1))
+ data[i+j] = '.';
+#endif /* CURL_DOES_CONVERSIONS */
printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
- else
+ } else
break;
puts("");
}
+#ifdef CURL_DOES_CONVERSIONS
+ curl_easy_cleanup(handle);
+#endif
free(base64); free(data);
return 0;
}
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
*
* $Id$
***************************************************************************/
-size_t Curl_base64_encode(const char *input, size_t size, char **str);
+size_t Curl_base64_encode(struct SessionHandle *data,
+ const char *input, size_t size, char **str);
size_t Curl_base64_decode(const char *source, unsigned char **outptr);
#endif
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
}
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
- if(Curl_base64_encode(data->state.buffer,
+ if(Curl_base64_encode(data, data->state.buffer,
strlen(data->state.buffer),
&authorization) > 0) {
if(*userp)
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
/* Generate a cnonce */
now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", now.tv_sec);
- if(Curl_base64_encode(cnoncebuf, strlen(cnoncebuf), &cnonce))
+ if(Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), &cnonce))
d->cnonce = cnonce;
else
return CURLE_OUT_OF_MEMORY;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
}
}
#endif
- len = Curl_base64_encode(neg_ctx->output_token.value,
+ len = Curl_base64_encode(conn->data,
+ neg_ctx->output_token.value,
neg_ctx->output_token.length,
&encoded);
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
});
/* now size is the size of the base64 encoded package size */
- size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
+ size = Curl_base64_encode(conn->data, (char *)ntlmbuf, size, &base64);
if(size >0 ) {
Curl_safefree(*allocuserpwd);
#endif
/* convert the binary blob into base64 */
- size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
+ size = Curl_base64_encode(conn->data, (char *)ntlmbuf, size, &base64);
if(size >0 ) {
Curl_safefree(*allocuserpwd);
*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
- * Copyright (c) 2004 - 2006 Daniel Stenberg
+ * Copyright (c) 2004 - 2007 Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
}
#endif
- if(Curl_base64_encode((char *)adat.dat, adat.length, &p) < 1) {
+ if(Curl_base64_encode(conn->data, (char *)adat.dat, adat.length, &p) < 1) {
Curl_failf(data, "Out of memory base64-encoding");
return AUTH_CONTINUE;
}
memset(key, 0, sizeof(key));
memset(schedule, 0, sizeof(schedule));
memset(passwd, 0, sizeof(passwd));
- if(Curl_base64_encode((char *)tktcopy.dat, tktcopy.length, &p) < 1) {
+ if(Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length, &p)
+ < 1) {
failf(conn->data, "Out of memory base64-encoding.");
Curl_set_command_prot(conn, save);
return CURLE_OUT_OF_MEMORY;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
(char *)attribute +
(strlen((char *)attribute) - 7)) == 0)) {
/* Binary attribute, encode to base64. */
- val_b64_sz = Curl_base64_encode(vals[i]->bv_val, vals[i]->bv_len,
+ val_b64_sz = Curl_base64_encode(conn->data,
+ vals[i]->bv_val,
+ vals[i]->bv_len,
&val_b64);
if (val_b64_sz > 0) {
Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);