From 359d5009089b8b9450ab54825c08448f9e51ed64 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 3 Jan 2007 23:04:38 +0000 Subject: [PATCH] - David McCreedy made changes to allow base64 encoding/decoding to work on non-ASCII platforms. --- CHANGES | 4 ++ RELEASE-NOTES | 1 + lib/base64.c | 96 ++++++++++++++++++++++++++++++++++---------- lib/base64.h | 5 ++- lib/http.c | 4 +- lib/http_digest.c | 4 +- lib/http_negotiate.c | 5 ++- lib/http_ntlm.c | 6 +-- lib/krb4.c | 7 ++-- lib/ldap.c | 6 ++- 10 files changed, 100 insertions(+), 38 deletions(-) diff --git a/CHANGES b/CHANGES index d46ed330a..811122d1d 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,10 @@ 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 diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 6ff132e7d..fe108df67 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -46,6 +46,7 @@ This release includes the following bugfixes: 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: diff --git a/lib/base64.c b/lib/base64.c index 2302eb014..aa03f8346 100644 --- a/lib/base64.c +++ b/lib/base64.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -40,28 +40,27 @@ #define _MPRINTF_REPLACE /* use our functions only */ #include +#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); } @@ -133,10 +132,6 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr) return rawlen; } -/* ---- Base64 Encoding --- */ -static const char table64[]= - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - /* * Curl_base64_encode() * @@ -145,7 +140,8 @@ static const char table64[]= * 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]; @@ -153,6 +149,9 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr) int inputparts; char *output; char *base64data; +#ifdef CURL_DOES_CONVERSIONS + char *convbuf; +#endif char *indata = (char *)inp; @@ -165,6 +164,28 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr) 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) { @@ -209,6 +230,10 @@ size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr) *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 ---- */ @@ -231,14 +256,26 @@ int main(int argc, char **argv, char **envp) 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 @@ -261,10 +298,17 @@ int main(int argc, char **argv, char **envp) 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); @@ -279,13 +323,21 @@ int main(int argc, char **argv, char **envp) 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; } diff --git a/lib/base64.h b/lib/base64.h index 0754908ca..59742bcd3 100644 --- a/lib/base64.h +++ b/lib/base64.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,6 +22,7 @@ * * $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 diff --git a/lib/http.c b/lib/http.c index 2f8b98e2e..ae7c3cfbc 100644 --- a/lib/http.c +++ b/lib/http.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -149,7 +149,7 @@ static CURLcode Curl_output_basic(struct connectdata *conn, bool proxy) } 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) diff --git a/lib/http_digest.c b/lib/http_digest.c index 8b605d5c5..e5d8baae5 100644 --- a/lib/http_digest.c +++ b/lib/http_digest.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -270,7 +270,7 @@ CURLcode Curl_output_digest(struct connectdata *conn, /* 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; diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c index eb5bd92d1..bdfeefa0a 100644 --- a/lib/http_negotiate.c +++ b/lib/http_negotiate.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -290,7 +290,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn) } } #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); diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index 4bbd0dda7..ee6f6eb9b 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -706,7 +706,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, }); /* 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); @@ -1017,7 +1017,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, #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); diff --git a/lib/krb4.c b/lib/krb4.c index 1659be21d..f2b91df69 100644 --- a/lib/krb4.c +++ b/lib/krb4.c @@ -7,7 +7,7 @@ * * 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 @@ -252,7 +252,7 @@ krb4_auth(void *app_data, struct connectdata *conn) } #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; } @@ -400,7 +400,8 @@ CURLcode Curl_krb_kauth(struct connectdata *conn) 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; diff --git a/lib/ldap.c b/lib/ldap.c index 53c772209..3e1144d4f 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -402,7 +402,9 @@ CURLcode Curl_ldap(struct connectdata *conn, bool *done) (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);