diff -urN curl-7.19.0/lib/cookie.c curl-7.19.0-patched/lib/cookie.c --- curl-7.19.0/lib/cookie.c 2008-08-28 04:35:54.000000000 -0700 +++ curl-7.19.0-patched/lib/cookie.c 2008-10-23 22:26:36.000000000 -0700 @@ -96,6 +96,7 @@ #include "memory.h" #include "share.h" #include "strtoofft.h" +#include "rawstr.h" /* The last #include file should be: */ #ifdef CURLDEBUG @@ -243,14 +244,14 @@ whatptr++; } - if(strequal("path", name)) { + if(Curl_raw_equal("path", name)) { co->path=strdup(whatptr); if(!co->path) { badcookie = TRUE; /* out of memory bad */ break; } } - else if(strequal("domain", name)) { + else if(Curl_raw_equal("domain", name)) { /* note that this name may or may not have a preceeding dot, but we don't care about that, we treat the names the same anyway */ @@ -315,14 +316,14 @@ } } } - else if(strequal("version", name)) { + else if(Curl_raw_equal("version", name)) { co->version=strdup(whatptr); if(!co->version) { badcookie = TRUE; break; } } - else if(strequal("max-age", name)) { + else if(Curl_raw_equal("max-age", name)) { /* Defined in RFC2109: Optional. The Max-Age attribute defines the lifetime of the @@ -340,7 +341,7 @@ co->expires = atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + (long)now; } - else if(strequal("expires", name)) { + else if(Curl_raw_equal("expires", name)) { co->expirestr=strdup(whatptr); if(!co->expirestr) { badcookie = TRUE; @@ -367,10 +368,10 @@ else { if(sscanf(ptr, "%" MAX_COOKIE_LINE_TXT "[^;\r\n]", what)) { - if(strequal("secure", what)) { + if(Curl_raw_equal("secure", what)) { co->secure = TRUE; } - else if (strequal("httponly", what)) { + else if (Curl_raw_equal("httponly", what)) { co->httponly = TRUE; } /* else, @@ -494,7 +495,7 @@ As far as I can see, it is set to true when the cookie says .domain.com and to false when the domain is complete www.domain.com */ - co->tailmatch=(bool)strequal(ptr, "TRUE"); /* store information */ + co->tailmatch=(bool)Curl_raw_equal(ptr, "TRUE"); /* store information */ break; case 2: /* It turns out, that sometimes the file format allows the path @@ -514,7 +515,7 @@ fields++; /* add a field and fall down to secure */ /* FALLTHROUGH */ case 3: - co->secure = (bool)strequal(ptr, "TRUE"); + co->secure = (bool)Curl_raw_equal(ptr, "TRUE"); break; case 4: co->expires = curlx_strtoofft(ptr, NULL, 10); @@ -567,11 +568,11 @@ clist = c->cookies; replace_old = FALSE; while(clist) { - if(strequal(clist->name, co->name)) { + if(Curl_raw_equal(clist->name, co->name)) { /* the names are identical */ if(clist->domain && co->domain) { - if(strequal(clist->domain, co->domain)) + if(Curl_raw_equal(clist->domain, co->domain)) /* The domains are identical */ replace_old=TRUE; } @@ -582,7 +583,7 @@ /* the domains were identical */ if(clist->path && co->path) { - if(strequal(clist->path, co->path)) { + if(Curl_raw_equal(clist->path, co->path)) { replace_old = TRUE; } else @@ -775,7 +776,7 @@ /* now check if the domain is correct */ if(!co->domain || (co->tailmatch && tailmatch(co->domain, host)) || - (!co->tailmatch && strequal(host, co->domain)) ) { + (!co->tailmatch && Curl_raw_equal(host, co->domain)) ) { /* the right part of the host matches the domain stuff in the cookie data */ diff -urN curl-7.19.0/lib/curlx.h curl-7.19.0-patched/lib/curlx.h --- curl-7.19.0/lib/curlx.h 2006-10-27 00:23:12.000000000 -0700 +++ curl-7.19.0-patched/lib/curlx.h 2008-10-23 22:26:26.000000000 -0700 @@ -65,6 +65,7 @@ #define curlx_getenv curl_getenv #define curlx_strequal curl_strequal #define curlx_strnequal curl_strnequal +#define curlx_raw_equal Curl_raw_equal #define curlx_mvsnprintf curl_mvsnprintf #define curlx_msnprintf curl_msnprintf #define curlx_maprintf curl_maprintf diff -urN curl-7.19.0/lib/dict.c curl-7.19.0-patched/lib/dict.c --- curl-7.19.0/lib/dict.c 2007-12-08 15:03:52.000000000 -0800 +++ curl-7.19.0-patched/lib/dict.c 2008-10-23 22:26:36.000000000 -0700 @@ -75,6 +75,7 @@ #include "progress.h" #include "strequal.h" #include "dict.h" +#include "rawstr.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> diff -urN curl-7.19.0/lib/gtls.c curl-7.19.0-patched/lib/gtls.c --- curl-7.19.0/lib/gtls.c 2008-06-10 14:53:59.000000000 -0700 +++ curl-7.19.0-patched/lib/gtls.c 2008-10-23 22:26:26.000000000 -0700 @@ -223,9 +223,9 @@ { if(!type || !type[0]) return GNUTLS_X509_FMT_PEM; - if(curl_strequal(type, "PEM")) + if(Curl_raw_equal(type, "PEM")) return GNUTLS_X509_FMT_PEM; - if(curl_strequal(type, "DER")) + if(Curl_raw_equal(type, "DER")) return GNUTLS_X509_FMT_DER; return -1; } diff -urN curl-7.19.0/lib/http.c curl-7.19.0-patched/lib/http.c --- curl-7.19.0/lib/http.c 2008-08-19 12:02:45.000000000 -0700 +++ curl-7.19.0-patched/lib/http.c 2008-10-23 22:26:36.000000000 -0700 @@ -97,6 +97,7 @@ #include "parsedate.h" /* for the week day and month names */ #include "strtoofft.h" #include "multiif.h" +#include "rawstr.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> @@ -611,7 +612,7 @@ if(!data->state.this_is_a_follow || conn->bits.netrc || !data->state.first_host || - curl_strequal(data->state.first_host, conn->host.name) || + Curl_raw_equal(data->state.first_host, conn->host.name) || data->set.http_disable_hostname_check_before_authentication) { /* Send web authentication header if needed */ @@ -2157,7 +2158,7 @@ ptr = checkheaders(data, "Host:"); if(ptr && (!data->state.this_is_a_follow || - curl_strequal(data->state.first_host, conn->host.name))) { + Curl_raw_equal(data->state.first_host, conn->host.name))) { #if !defined(CURL_DISABLE_COOKIES) /* If we have a given custom Host: header, we extract the host name in order to possibly use it for cookie reasons later on. We only allow the diff -urN curl-7.19.0/lib/http_digest.c curl-7.19.0-patched/lib/http_digest.c --- curl-7.19.0/lib/http_digest.c 2008-08-19 12:02:45.000000000 -0700 +++ curl-7.19.0-patched/lib/http_digest.c 2008-10-23 22:26:36.000000000 -0700 @@ -32,7 +32,7 @@ #include "urldata.h" #include "sendf.h" -#include "strequal.h" +#include "rawstr.h" #include "curl_base64.h" #include "curl_md5.h" #include "http_digest.h" @@ -104,28 +104,28 @@ include the possibly trailing comma, newline or carriage return */ (2 == sscanf(header, "%255[^=]=%1023[^\r\n,]", value, content)) ) { - if(strequal(value, "nonce")) { + if(Curl_raw_equal(value, "nonce")) { d->nonce = strdup(content); if(!d->nonce) return CURLDIGEST_NOMEM; } - else if(strequal(value, "stale")) { - if(strequal(content, "true")) { + else if(Curl_raw_equal(value, "stale")) { + if(Curl_raw_equal(content, "true")) { d->stale = TRUE; d->nc = 1; /* we make a new nonce now */ } } - else if(strequal(value, "realm")) { + else if(Curl_raw_equal(value, "realm")) { d->realm = strdup(content); if(!d->realm) return CURLDIGEST_NOMEM; } - else if(strequal(value, "opaque")) { + else if(Curl_raw_equal(value, "opaque")) { d->opaque = strdup(content); if(!d->opaque) return CURLDIGEST_NOMEM; } - else if(strequal(value, "qop")) { + else if(Curl_raw_equal(value, "qop")) { char *tok_buf; /* tokenize the list and choose auth if possible, use a temporary clone of the buffer since strtok_r() ruins it */ @@ -134,10 +134,10 @@ return CURLDIGEST_NOMEM; token = strtok_r(tmp, ",", &tok_buf); while(token != NULL) { - if(strequal(token, "auth")) { + if(Curl_raw_equal(token, "auth")) { foundAuth = TRUE; } - else if(strequal(token, "auth-int")) { + else if(Curl_raw_equal(token, "auth-int")) { foundAuthInt = TRUE; } token = strtok_r(NULL, ",", &tok_buf); @@ -155,13 +155,13 @@ return CURLDIGEST_NOMEM; } } - else if(strequal(value, "algorithm")) { + else if(Curl_raw_equal(value, "algorithm")) { d->algorithm = strdup(content); if(!d->algorithm) return CURLDIGEST_NOMEM; - if(strequal(content, "MD5-sess")) + if(Curl_raw_equal(content, "MD5-sess")) d->algo = CURLDIGESTALGO_MD5SESS; - else if(strequal(content, "MD5")) + else if(Curl_raw_equal(content, "MD5")) d->algo = CURLDIGESTALGO_MD5; else return CURLDIGEST_BADALGO; @@ -356,7 +356,7 @@ return CURLE_OUT_OF_MEMORY; } - if(d->qop && strequal(d->qop, "auth-int")) { + if(d->qop && Curl_raw_equal(d->qop, "auth-int")) { /* We don't support auth-int at the moment. I can't see a easy way to get entity-body here */ /* TODO: Append H(entity-body)*/ @@ -417,7 +417,7 @@ d->qop, request_digest); - if(strequal(d->qop, "auth")) + if(Curl_raw_equal(d->qop, "auth")) d->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 padded which tells to the server how many times you are using the same nonce in the qop=auth mode. */ diff -urN curl-7.19.0/lib/http_negotiate.c curl-7.19.0-patched/lib/http_negotiate.c --- curl-7.19.0/lib/http_negotiate.c 2008-08-19 12:02:45.000000000 -0700 +++ curl-7.19.0-patched/lib/http_negotiate.c 2008-10-23 22:26:36.000000000 -0700 @@ -37,7 +37,7 @@ #include "urldata.h" #include "sendf.h" -#include "strequal.h" +#include "rawstr.h" #include "curl_base64.h" #include "http_negotiate.h" #include "memory.h" diff -urN curl-7.19.0/lib/http_ntlm.c curl-7.19.0-patched/lib/http_ntlm.c --- curl-7.19.0/lib/http_ntlm.c 2008-08-19 12:02:45.000000000 -0700 +++ curl-7.19.0-patched/lib/http_ntlm.c 2008-10-23 22:26:36.000000000 -0700 @@ -55,7 +55,7 @@ #include "urldata.h" #include "easyif.h" /* for Curl_convert_... prototypes */ #include "sendf.h" -#include "strequal.h" +#include "rawstr.h" #include "curl_base64.h" #include "http_ntlm.h" #include "url.h" diff -urN curl-7.19.0/lib/ldap.c curl-7.19.0-patched/lib/ldap.c --- curl-7.19.0/lib/ldap.c 2008-08-19 12:02:45.000000000 -0700 +++ curl-7.19.0-patched/lib/ldap.c 2008-10-23 22:26:36.000000000 -0700 @@ -75,6 +75,7 @@ #include "curl_ldap.h" #include "memory.h" #include "curl_base64.h" +#include "rawstr.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> @@ -198,7 +199,7 @@ } /* Get the URL scheme ( either ldap or ldaps ) */ - if(strequal(conn->protostr, "LDAPS")) + if(Curl_raw_equal(conn->protostr, "LDAPS")) ldap_ssl = 1; infof(data, "LDAP local: trying to establish %s connection\n", ldap_ssl ? "encrypted" : "cleartext"); @@ -228,7 +229,7 @@ /* Novell SDK supports DER or BASE64 files. */ int cert_type = LDAPSSL_CERT_FILETYPE_B64; if((data->set.str[STRING_CERT_TYPE]) && - (strequal(data->set.str[STRING_CERT_TYPE], "DER"))) + (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER"))) cert_type = LDAPSSL_CERT_FILETYPE_DER; if(!ldap_ca) { failf(data, "LDAP local: ERROR %s CA cert not set!", @@ -269,7 +270,7 @@ if(data->set.ssl.verifypeer) { /* OpenLDAP SDK supports BASE64 files. */ if((data->set.str[STRING_CERT_TYPE]) && - (!strequal(data->set.str[STRING_CERT_TYPE], "PEM"))) { + (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) { failf(data, "LDAP local: ERROR OpenLDAP does only support PEM cert-type!"); status = CURLE_SSL_CERTPROBLEM; goto quit; diff -urN curl-7.19.0/lib/Makefile.inc curl-7.19.0-patched/lib/Makefile.inc --- curl-7.19.0/lib/Makefile.inc 2008-08-19 12:02:45.000000000 -0700 +++ curl-7.19.0-patched/lib/Makefile.inc 2008-10-23 22:26:36.000000000 -0700 @@ -9,7 +9,7 @@ http_negotiate.c http_ntlm.c inet_pton.c strtoofft.c strerror.c \ hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \ inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \ - strdup.c socks.c ssh.c nss.c qssl.c + strdup.c socks.c ssh.c nss.c qssl.c rawstr.c HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \ progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \ @@ -20,4 +20,4 @@ strtoofft.h strerror.h inet_ntop.h curlx.h memory.h setup.h \ transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h \ tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \ - curl_base64.h + curl_base64.h rawstr.h diff -urN curl-7.19.0/lib/netrc.c curl-7.19.0-patched/lib/netrc.c --- curl-7.19.0/lib/netrc.c 2008-08-03 11:00:59.000000000 -0700 +++ curl-7.19.0-patched/lib/netrc.c 2008-10-23 22:26:36.000000000 -0700 @@ -43,6 +43,7 @@ #include "strequal.h" #include "strtok.h" #include "memory.h" +#include "rawstr.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> @@ -155,7 +156,7 @@ switch(state) { case NOTHING: - if(strequal("machine", tok)) { + if(Curl_raw_equal("machine", tok)) { /* the next tok is the machine name, this is in itself the delimiter that starts the stuff entered for this machine, after this we need to search for 'login' and @@ -164,7 +165,7 @@ } break; case HOSTFOUND: - if(strequal(host, tok)) { + if(Curl_raw_equal(host, tok)) { /* and yes, this is our host! */ state=HOSTVALID; #ifdef _NETRC_DEBUG @@ -180,7 +181,7 @@ /* we are now parsing sub-keywords concerning "our" host */ if(state_login) { if(specific_login) { - state_our_login = strequal(login, tok); + state_our_login = Curl_raw_equal(login, tok); } else { strncpy(login, tok, LOGINSIZE-1); @@ -199,11 +200,11 @@ } state_password=0; } - else if(strequal("login", tok)) + else if(Curl_raw_equal("login", tok)) state_login=1; - else if(strequal("password", tok)) + else if(Curl_raw_equal("password", tok)) state_password=1; - else if(strequal("machine", tok)) { + else if(Curl_raw_equal("machine", tok)) { /* ok, there's machine here go => */ state = HOSTFOUND; state_our_login = FALSE; diff -urN curl-7.19.0/lib/nss.c curl-7.19.0-patched/lib/nss.c --- curl-7.19.0/lib/nss.c 2008-06-23 15:32:13.000000000 -0700 +++ curl-7.19.0-patched/lib/nss.c 2008-10-23 22:26:26.000000000 -0700 @@ -43,7 +43,6 @@ #include "strequal.h" #include "select.h" #include "sslgen.h" -#include "strequal.h" #define _MPRINTF_REPLACE /* use the internal *printf() functions */ #include <curl/mprintf.h> @@ -200,7 +199,7 @@ found = PR_FALSE; for(i=0; i<NUM_OF_CIPHERS; i++) { - if(strequal(cipher, cipherlist[i].name)) { + if(Curl_raw_equal(cipher, cipherlist[i].name)) { cipher_state[i] = PR_TRUE; found = PR_TRUE; break; diff -urN curl-7.19.0/lib/parsedate.c curl-7.19.0-patched/lib/parsedate.c --- curl-7.19.0/lib/parsedate.c 2008-06-22 13:27:56.000000000 -0700 +++ curl-7.19.0-patched/lib/parsedate.c 2008-10-23 22:26:36.000000000 -0700 @@ -83,6 +83,7 @@ #endif #include <curl/curl.h> +#include "rawstr.h" const char * const Curl_wkday[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; @@ -162,7 +163,7 @@ else what = &Curl_wkday[0]; for(i=0; i<7; i++) { - if(curl_strequal(check, what[0])) { + if(Curl_raw_equal(check, what[0])) { found=TRUE; break; } @@ -179,7 +180,7 @@ what = &Curl_month[0]; for(i=0; i<12; i++) { - if(curl_strequal(check, what[0])) { + if(Curl_raw_equal(check, what[0])) { found=TRUE; break; } @@ -199,7 +200,7 @@ what = tz; for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) { - if(curl_strequal(check, what->name)) { + if(Curl_raw_equal(check, what->name)) { found=TRUE; break; } diff -urN curl-7.19.0/lib/rawstr.c curl-7.19.0-patched/lib/rawstr.c --- curl-7.19.0/lib/rawstr.c 1969-12-31 16:00:00.000000000 -0800 +++ curl-7.19.0-patched/lib/rawstr.c 2008-10-23 22:26:36.000000000 -0700 @@ -0,0 +1,128 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, 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 + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: rawstr.c,v 1.1 2008-10-23 11:49:19 bagder Exp $ + ***************************************************************************/ + +#include "setup.h" + +#include "rawstr.h" + +/* Portable toupper (remember EBCDIC). Do not use tupper() because + its behavior is altered by the current locale. */ +static unsigned char my_toupper(unsigned char in) +{ + switch (in) { + case 'a': + return 'A'; + case 'b': + return 'B'; + case 'c': + return 'C'; + case 'd': + return 'D'; + case 'e': + return 'E'; + case 'f': + return 'F'; + case 'g': + return 'G'; + case 'h': + return 'H'; + case 'i': + return 'I'; + case 'j': + return 'J'; + case 'k': + return 'K'; + case 'l': + return 'L'; + case 'm': + return 'M'; + case 'n': + return 'N'; + case 'o': + return 'O'; + case 'p': + return 'P'; + case 'q': + return 'Q'; + case 'r': + return 'R'; + case 's': + return 'S'; + case 't': + return 'T'; + case 'u': + return 'U'; + case 'v': + return 'V'; + case 'w': + return 'W'; + case 'x': + return 'X'; + case 'y': + return 'Y'; + case 'z': + return 'Z'; + } + return in; +} + +/* + * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant + * to be locale independent and only compare strings we know are safe for + * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for + * some further explanation to why this function is necessary. + * + * The function is capable of comparing a-z case insensitively even for non-ascii. + */ + +int Curl_raw_equal(const char *first, const char *second) +{ + while(*first && *second) { + if(my_toupper(*first) != my_toupper(*second)) + /* get out of the loop as soon as they don't match */ + break; + first++; + second++; + } + /* we do the comparison here (possibly again), just to make sure that if the + loop above is skipped because one of the strings reached zero, we must not + return this as a successful match */ + return (my_toupper(*first) == my_toupper(*second)); +} + +int Curl_raw_nequal(const char *first, const char *second, size_t max) +{ + while(*first && *second && max) { + if(my_toupper(*first) != my_toupper(*second)) { + break; + } + max--; + first++; + second++; + } + if(0 == max) + return 1; /* they are equal this far */ + + return my_toupper(*first) == my_toupper(*second); +} + diff -urN curl-7.19.0/lib/rawstr.h curl-7.19.0-patched/lib/rawstr.h --- curl-7.19.0/lib/rawstr.h 1969-12-31 16:00:00.000000000 -0800 +++ curl-7.19.0-patched/lib/rawstr.h 2008-10-23 22:26:36.000000000 -0700 @@ -0,0 +1,42 @@ +#ifndef __RAWSTR_H +#define __RAWSTR_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, 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 + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: rawstr.h,v 1.1 2008-10-23 11:49:19 bagder Exp $ + ***************************************************************************/ + +#include <curl/curl.h> + +/* + * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant + * to be locale independent and only compare strings we know are safe for + * this. + * + * The function is capable of comparing a-z case insensitively even for non-ascii. + */ +int Curl_raw_equal(const char *first, const char *second); +int Curl_raw_nequal(const char *first, const char *second, size_t max); + +/* checkprefix() is a shorter version of the above, used when the first + argument is zero-byte terminated */ +#define checkprefix(a,b) Curl_raw_nequal(a,b,strlen(a)) + +#endif diff -urN curl-7.19.0/lib/sslgen.c curl-7.19.0-patched/lib/sslgen.c --- curl-7.19.0/lib/sslgen.c 2008-07-02 23:56:03.000000000 -0700 +++ curl-7.19.0-patched/lib/sslgen.c 2008-10-23 22:26:36.000000000 -0700 @@ -57,7 +57,7 @@ #include "nssg.h" /* NSS versions */ #include "qssl.h" /* QSOSSL versions */ #include "sendf.h" -#include "strequal.h" +#include "rawstr.h" #include "url.h" #include "memory.h" #include "progress.h" @@ -70,7 +70,7 @@ { if(str1 && str2) /* both pointers point to something then compare them */ - return (bool)(0 != strequal(str1, str2)); + return (bool)(0 != Curl_raw_equal(str1, str2)); else /* if both pointers are NULL then treat them as equal */ return (bool)(!str1 && !str2); diff -urN curl-7.19.0/lib/ssluse.c curl-7.19.0-patched/lib/ssluse.c --- curl-7.19.0/lib/ssluse.c 2008-07-30 14:24:59.000000000 -0700 +++ curl-7.19.0-patched/lib/ssluse.c 2008-10-23 22:26:26.000000000 -0700 @@ -284,13 +284,13 @@ { if(!type || !type[0]) return SSL_FILETYPE_PEM; - if(curl_strequal(type, "PEM")) + if(Curl_raw_equal(type, "PEM")) return SSL_FILETYPE_PEM; - if(curl_strequal(type, "DER")) + if(Curl_raw_equal(type, "DER")) return SSL_FILETYPE_ASN1; - if(curl_strequal(type, "ENG")) + if(Curl_raw_equal(type, "ENG")) return SSL_FILETYPE_ENGINE; - if(curl_strequal(type, "P12")) + if(Curl_raw_equal(type, "P12")) return SSL_FILETYPE_PKCS12; return -1; } @@ -987,7 +987,7 @@ !hostname || !*hostname) /* sanity check */ return 0; - if(curl_strequal(hostname,match_pattern)) /* trivial case */ + if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */ return 1; if(hostmatch(hostname,match_pattern) == HOST_MATCH) diff -urN curl-7.19.0/lib/strequal.h curl-7.19.0-patched/lib/strequal.h --- curl-7.19.0/lib/strequal.h 2005-04-22 13:48:07.000000000 -0700 +++ curl-7.19.0-patched/lib/strequal.h 2008-10-23 22:26:26.000000000 -0700 @@ -35,6 +35,15 @@ /* case insensitive strstr() */ char *Curl_strcasestr(const char *haystack, const char *needle); +/* + * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant + * to be locale independent and only compare strings we know are safe for + * this. + * + * The function is capable of comparing a-z case insensitively even for non-ascii. + */ +int Curl_raw_equal(const char *first, const char *second); + #ifndef HAVE_STRLCAT #define strlcat(x,y,z) Curl_strlcat(x,y,z) #endif diff -urN curl-7.19.0/lib/telnet.c curl-7.19.0-patched/lib/telnet.c --- curl-7.19.0/lib/telnet.c 2008-06-04 08:36:10.000000000 -0700 +++ curl-7.19.0-patched/lib/telnet.c 2008-10-23 22:26:36.000000000 -0700 @@ -77,6 +77,7 @@ #include "arpa_telnet.h" #include "memory.h" #include "select.h" +#include "rawstr.h" /* The last #include file should be: */ #include "memdebug.h" @@ -834,7 +835,7 @@ option_keyword, option_arg) == 2) { /* Terminal type */ - if(curl_strequal(option_keyword, "TTYPE")) { + if(Curl_raw_equal(option_keyword, "TTYPE")) { strncpy(tn->subopt_ttype, option_arg, 31); tn->subopt_ttype[31] = 0; /* String termination */ tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES; @@ -842,7 +843,7 @@ } /* Display variable */ - if(curl_strequal(option_keyword, "XDISPLOC")) { + if(Curl_raw_equal(option_keyword, "XDISPLOC")) { strncpy(tn->subopt_xdisploc, option_arg, 127); tn->subopt_xdisploc[127] = 0; /* String termination */ tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES; @@ -850,7 +851,7 @@ } /* Environment variable */ - if(curl_strequal(option_keyword, "NEW_ENV")) { + if(Curl_raw_equal(option_keyword, "NEW_ENV")) { buf = strdup(option_arg); if(!buf) return CURLE_OUT_OF_MEMORY; diff -urN curl-7.19.0/lib/transfer.c curl-7.19.0-patched/lib/transfer.c --- curl-7.19.0/lib/transfer.c 2008-08-29 03:47:59.000000000 -0700 +++ curl-7.19.0-patched/lib/transfer.c 2008-10-23 22:26:36.000000000 -0700 @@ -33,6 +33,7 @@ #include "strtoofft.h" #include "strequal.h" +#include "rawstr.h" #ifdef WIN32 #include <time.h> diff -urN curl-7.19.0/lib/url.c curl-7.19.0-patched/lib/url.c --- curl-7.19.0/lib/url.c 2008-08-28 00:37:29.000000000 -0700 +++ curl-7.19.0-patched/lib/url.c 2008-10-23 22:26:36.000000000 -0700 @@ -122,6 +122,7 @@ #include "multiif.h" #include "easyif.h" #include "speedcheck.h" +#include "rawstr.h" /* And now for the protocols */ #include "ftp.h" @@ -1247,17 +1248,17 @@ if(argptr == NULL) break; - if(strequal(argptr, "ALL")) { + if(Curl_raw_equal(argptr, "ALL")) { /* clear all cookies */ Curl_cookie_clearall(data->cookies); break; } - else if(strequal(argptr, "SESS")) { + else if(Curl_raw_equal(argptr, "SESS")) { /* clear session cookies */ Curl_cookie_clearsess(data->cookies); break; } - else if(strequal(argptr, "FLUSH")) { + else if(Curl_raw_equal(argptr, "FLUSH")) { /* flush cookies to file */ flush_cookies(data, 0); break; @@ -2479,14 +2480,14 @@ if(!needle->bits.httpproxy || needle->protocol&PROT_SSL || (needle->bits.httpproxy && check->bits.httpproxy && needle->bits.tunnel_proxy && check->bits.tunnel_proxy && - strequal(needle->proxy.name, check->proxy.name) && + Curl_raw_equal(needle->proxy.name, check->proxy.name) && (needle->port == check->port))) { /* The requested connection does not use a HTTP proxy or it uses SSL or it is a non-SSL protocol tunneled over the same http proxy name and port number */ - if(strequal(needle->protostr, check->protostr) && - strequal(needle->host.name, check->host.name) && + if(Curl_raw_equal(needle->protostr, check->protostr) && + Curl_raw_equal(needle->host.name, check->host.name) && (needle->remote_port == check->remote_port) ) { if(needle->protocol & PROT_SSL) { /* This is SSL, verify that we're using the same @@ -2512,8 +2513,8 @@ (data->state.authhost.want==CURLAUTH_NTLM))) { /* This is FTP or HTTP+NTLM, verify that we're using the same name and password as well */ - if(!strequal(needle->user, check->user) || - !strequal(needle->passwd, check->passwd)) { + if(!Curl_raw_equal(needle->user, check->user) || + !Curl_raw_equal(needle->passwd, check->passwd)) { /* one of them was different */ continue; } @@ -2525,7 +2526,7 @@ is the checked one using the same host, port and type? */ if(check->bits.proxy && (needle->proxytype == check->proxytype) && - strequal(needle->proxy.name, check->proxy.name) && + Curl_raw_equal(needle->proxy.name, check->proxy.name) && needle->port == check->port) { /* This is the same proxy connection, use it! */ match = TRUE; @@ -3003,7 +3004,7 @@ ************************************************************/ if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", conn->protostr, - path)) && strequal(conn->protostr, "file")) { + path)) && Curl_raw_equal(conn->protostr, "file")) { if(path[0] == '/' && path[1] == '/') { /* Allow omitted hostname (e.g. file:/<path>). This is not strictly * speaking a valid file: URL by RFC 1738, but treating file:/<path> as @@ -3238,7 +3239,7 @@ /* Scan protocol handler table. */ for (pp = protocols; (p = *pp) != NULL; pp++) - if(strequal(p->scheme, conn->protostr)) { + if(Curl_raw_equal(p->scheme, conn->protostr)) { /* Protocol found in table. Perform setup complement if some. */ conn->handler = p; @@ -3300,7 +3301,7 @@ if(!no_proxy) no_proxy=curl_getenv("NO_PROXY"); - if(!no_proxy || !strequal("*", no_proxy)) { + if(!no_proxy || !Curl_raw_equal("*", no_proxy)) { /* NO_PROXY wasn't specified or it wasn't just an asterisk */ char *nope; @@ -3351,7 +3352,7 @@ * This can cause 'internal' http/ftp requests to be * arbitrarily redirected by any external attacker. */ - if(!prox && !strequal("http_proxy", proxy_env)) { + if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) { /* There was no lowercase variable, try the uppercase version: */ for(envp = proxy_env; *envp; envp++) *envp = (char)toupper((int)*envp); @@ -3671,8 +3672,8 @@ if(conn->bits.httpproxy) { /* we need to create new URL with the new port number */ char *url; - bool isftp = strequal("ftp", conn->protostr) || - strequal("ftps", conn->protostr); + bool isftp = Curl_raw_equal("ftp", conn->protostr) || + Curl_raw_equal("ftps", conn->protostr); /* * This synthesized URL isn't always right--suffixes like ;type=A diff -urN curl-7.19.0/src/main.c curl-7.19.0-patched/src/main.c --- curl-7.19.0/src/main.c 2008-08-29 01:55:20.000000000 -0700 +++ curl-7.19.0-patched/src/main.c 2008-10-23 22:26:36.000000000 -0700 @@ -44,6 +44,7 @@ #ifdef USE_ENVIRONMENT #include "writeenv.h" #endif +#include "rawstr.h" #define CURLseparator "--_curl_--" @@ -1501,11 +1502,11 @@ static int ftpfilemethod(struct Configurable *config, const char *str) { - if(curlx_strequal("singlecwd", str)) + if(curlx_raw_equal("singlecwd", str)) return CURLFTPMETHOD_SINGLECWD; - if(curlx_strequal("nocwd", str)) + if(curlx_raw_equal("nocwd", str)) return CURLFTPMETHOD_NOCWD; - if(curlx_strequal("multicwd", str)) + if(curlx_raw_equal("multicwd", str)) return CURLFTPMETHOD_MULTICWD; warnf(config, "unrecognized ftp file method '%s', using default\n", str); return CURLFTPMETHOD_MULTICWD; @@ -1513,9 +1514,9 @@ static int ftpcccmethod(struct Configurable *config, const char *str) { - if(curlx_strequal("passive", str)) + if(curlx_raw_equal("passive", str)) return CURLFTPSSL_CCC_PASSIVE; - if(curlx_strequal("active", str)) + if(curlx_raw_equal("active", str)) return CURLFTPSSL_CCC_ACTIVE; warnf(config, "unrecognized ftp CCC method '%s', using default\n", str); return CURLFTPSSL_CCC_PASSIVE; @@ -1764,7 +1765,7 @@ if(curlx_strnequal(aliases[j].lname, word, fnam)) { longopt = TRUE; numhits++; - if(curlx_strequal(aliases[j].lname, word)) { + if(curlx_raw_equal(aliases[j].lname, word)) { parse = aliases[j].letter; hit = j; numhits = 1; /* a single unique hit */ @@ -2446,7 +2447,7 @@ break; case 'f': /* crypto engine */ GetStr(&config->engine, nextarg); - if (config->engine && curlx_strequal(config->engine,"list")) + if (config->engine && curlx_raw_equal(config->engine,"list")) config->list_engines = TRUE; break; case 'g': /* CA info PEM file */ diff -urN curl-7.19.0/src/Makefile.inc curl-7.19.0-patched/src/Makefile.inc --- curl-7.19.0/src/Makefile.inc 2007-11-18 16:02:25.000000000 -0800 +++ curl-7.19.0-patched/src/Makefile.inc 2008-10-23 22:26:36.000000000 -0700 @@ -3,7 +3,8 @@ # libcurl has sources that provide functions named curlx_* that aren't part of # the official API, but we re-use the code here to avoid duplication. CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \ - $(top_srcdir)/lib/strdup.c + $(top_srcdir)/lib/strdup.c \ + $(top_srcdir)/lib/rawstr.c CURL_SOURCES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \ getpass.c homedir.c curlutil.c