Fixed a couple more locale-dependent toupper conversions, mainly for

clarity.  This does fix one problem that causes ;type=i FTP URLs
to fail in the Turkish locale when CURLOPT_PROXY_TRANSFER_MODE is
used (test case 561)

Added tests 561 and 1092 through 1094 to test various combinations
of ;type= and ;mode= URLs that could potentially fail in the Turkish
locale.
This commit is contained in:
Dan Fandrich 2009-01-21 04:42:47 +00:00
parent 6bb9ef8de4
commit 5591550167
17 changed files with 314 additions and 27 deletions

13
CHANGES
View File

@ -6,6 +6,19 @@
Changelog Changelog
Daniel Fandrich (20 Jan 2009)
- Call setlocale() for libtest tests to test the effects of locale-induced
libc changes on libcurl.
- Fixed a couple more locale-dependent toupper conversions, mainly for
clarity. This does fix one problem that causes ;type=i FTP URLs
to fail in the Turkish locale when CURLOPT_PROXY_TRANSFER_MODE is
used (test case 561)
- Added tests 561 and 1091 through 1094 to test various combinations
of ;type= and ;mode= URLs that could potentially fail in the Turkish
locale.
Daniel Stenberg (20 Jan 2009) Daniel Stenberg (20 Jan 2009)
- Lisa Xu pointed out that the ssh.obj file was missing from the lib/Makefile.vc6 - Lisa Xu pointed out that the ssh.obj file was missing from the lib/Makefile.vc6
file (and thus from the vc8 and vc9 ones too). file (and thus from the vc8 and vc9 ones too).

View File

@ -14,6 +14,7 @@ This release includes the following changes:
This release includes the following bugfixes: This release includes the following bugfixes:
o missing ssh.obj in VS makefiles o missing ssh.obj in VS makefiles
o FTP ;type=i URLs now work with CURLOPT_PROXY_TRANSFER_MODE in Turkish locale
This release includes the following known bugs: This release includes the following known bugs:

View File

@ -89,6 +89,7 @@
#include "sockaddr.h" /* required for Curl_sockaddr_storage */ #include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "multiif.h" #include "multiif.h"
#include "url.h" #include "url.h"
#include "rawstr.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@ -4141,7 +4142,7 @@ static CURLcode ftp_setup_connection(struct connectdata * conn)
if(type) { if(type) {
*type = 0; /* it was in the middle of the hostname */ *type = 0; /* it was in the middle of the hostname */
command = (char) toupper((int) type[6]); command = Curl_raw_toupper(type[6]);
switch (command) { switch (command) {
case 'A': /* ASCII mode */ case 'A': /* ASCII mode */

View File

@ -2271,7 +2271,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(checkprefix("ftp://", ppath) || checkprefix("ftps://", ppath)) { if(checkprefix("ftp://", ppath) || checkprefix("ftps://", ppath)) {
char *p = strstr(ppath, ";type="); char *p = strstr(ppath, ";type=");
if(p && p[6] && p[7] == 0) { if(p && p[6] && p[7] == 0) {
switch (toupper((int)((unsigned char)p[6]))) { switch (Curl_raw_toupper(p[6])) {
case 'A': case 'A':
case 'D': case 'D':
case 'I': case 'I':

View File

@ -323,7 +323,7 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
* key schedule ks is also set. * key schedule ks is also set.
*/ */
static void setup_des_key(unsigned char *key_56, static void setup_des_key(const unsigned char *key_56,
DES_key_schedule DESKEYARG(ks)) DES_key_schedule DESKEYARG(ks))
{ {
DES_cblock key; DES_cblock key;
@ -346,9 +346,9 @@ static void setup_des_key(unsigned char *key_56,
* 8 byte plaintext is encrypted with each key and the resulting 24 * 8 byte plaintext is encrypted with each key and the resulting 24
* bytes are stored in the results array. * bytes are stored in the results array.
*/ */
static void lm_resp(unsigned char *keys, static void lm_resp(const unsigned char *keys,
unsigned char *plaintext, const unsigned char *plaintext,
unsigned char *results) unsigned char *results)
{ {
DES_key_schedule ks; DES_key_schedule ks;
@ -377,17 +377,10 @@ static void mk_lm_hash(struct SessionHandle *data,
static const unsigned char magic[] = { static const unsigned char magic[] = {
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */ 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
}; };
unsigned int i; size_t len = CURLMIN(strlen(password), 14);
size_t len = strlen(password);
if(len > 14) Curl_strntoupper((char *)pw, password, len);
len = 14; memset(&pw[len], 0, 14-len);
for (i=0; i<len; i++)
pw[i] = (unsigned char)toupper(password[i]);
for (; i<14; i++)
pw[i] = 0;
#ifdef CURL_DOES_CONVERSIONS #ifdef CURL_DOES_CONVERSIONS
/* /*

View File

@ -25,9 +25,9 @@
#include "rawstr.h" #include "rawstr.h"
/* Portable toupper (remember EBCDIC). Do not use tupper() because /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
its behavior is altered by the current locale. */ its behavior is altered by the current locale. */
static unsigned char my_toupper(unsigned char in) char Curl_raw_toupper(char in)
{ {
switch (in) { switch (in) {
case 'a': case 'a':
@ -98,7 +98,7 @@ static unsigned char my_toupper(unsigned char in)
int Curl_raw_equal(const char *first, const char *second) int Curl_raw_equal(const char *first, const char *second)
{ {
while(*first && *second) { while(*first && *second) {
if(my_toupper(*first) != my_toupper(*second)) if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
/* get out of the loop as soon as they don't match */ /* get out of the loop as soon as they don't match */
break; break;
first++; first++;
@ -107,13 +107,13 @@ int Curl_raw_equal(const char *first, const char *second)
/* we do the comparison here (possibly again), just to make sure that if the /* 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 loop above is skipped because one of the strings reached zero, we must not
return this as a successful match */ return this as a successful match */
return (my_toupper(*first) == my_toupper(*second)); return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
} }
int Curl_raw_nequal(const char *first, const char *second, size_t max) int Curl_raw_nequal(const char *first, const char *second, size_t max)
{ {
while(*first && *second && max) { while(*first && *second && max) {
if(my_toupper(*first) != my_toupper(*second)) { if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
break; break;
} }
max--; max--;
@ -123,6 +123,6 @@ int Curl_raw_nequal(const char *first, const char *second, size_t max)
if(0 == max) if(0 == max)
return 1; /* they are equal this far */ return 1; /* they are equal this far */
return my_toupper(*first) == my_toupper(*second); return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
} }

View File

@ -35,6 +35,8 @@
int Curl_raw_equal(const char *first, const char *second); int Curl_raw_equal(const char *first, const char *second);
int Curl_raw_nequal(const char *first, const char *second, size_t max); int Curl_raw_nequal(const char *first, const char *second, size_t max);
char Curl_raw_toupper(char in);
/* checkprefix() is a shorter version of the above, used when the first /* checkprefix() is a shorter version of the above, used when the first
argument is zero-byte terminated */ argument is zero-byte terminated */
#define checkprefix(a,b) Curl_raw_nequal(a,b,strlen(a)) #define checkprefix(a,b) Curl_raw_nequal(a,b,strlen(a))

View File

@ -994,7 +994,7 @@ static int hostmatch(const char *hostname, const char *pattern)
break; break;
} }
if(toupper(c) != toupper(*hostname++)) if(Curl_raw_toupper(c) != Curl_raw_toupper(*hostname++))
break; break;
} }
return HOST_NOMATCH; return HOST_NOMATCH;

View File

@ -72,6 +72,7 @@
#include "strerror.h" #include "strerror.h"
#include "sockaddr.h" /* required for Curl_sockaddr_storage */ #include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "url.h" #include "url.h"
#include "rawstr.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@ -904,7 +905,7 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
if(type) { if(type) {
*type = 0; /* it was in the middle of the hostname */ *type = 0; /* it was in the middle of the hostname */
command = (char) toupper((int) type[6]); command = Curl_raw_toupper(type[6]);
switch (command) { switch (command) {
case 'A': /* ASCII mode */ case 'A': /* ASCII mode */

View File

@ -230,6 +230,21 @@ void Curl_safefree(void *ptr)
free(ptr); free(ptr);
} }
/* Copy an upper case version of the string from src to dest. The
* strings may overlap. No more than n characters of the string are copied
* (including any NUL) and the destination string will NOT be
* NUL-terminated if that limit is reached.
*/
void Curl_strntoupper(char *dest, const char *src, size_t n)
{
if (n < 1)
return;
do {
*dest++ = Curl_raw_toupper(*src);
} while (*src++ && --n);
}
static void close_connections(struct SessionHandle *data) static void close_connections(struct SessionHandle *data)
{ {
/* Loop through all open connections and kill them one by one */ /* Loop through all open connections and kill them one by one */
@ -3441,8 +3456,7 @@ static char *detect_proxy(struct connectdata *conn)
*/ */
if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) { if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
/* There was no lowercase variable, try the uppercase version: */ /* There was no lowercase variable, try the uppercase version: */
for(envp = proxy_env; *envp; envp++) Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
*envp = (char)toupper((int)*envp);
prox=curl_getenv(proxy_env); prox=curl_getenv(proxy_env);
} }

View File

@ -48,6 +48,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done); CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done); CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
void Curl_safefree(void *ptr); void Curl_safefree(void *ptr);
void Curl_strntoupper(char *dest, const char *src, size_t n);
/* create a connection cache */ /* create a connection cache */
struct conncache *Curl_mk_connc(int type, long amount); struct conncache *Curl_mk_connc(int type, long amount);

View File

@ -60,7 +60,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 \ test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 \
test1080 test1081 test1082 test1083 test1084 test1085 test633 test634 \ test1080 test1081 test1082 test1083 test1084 test1085 test633 test634 \
test635 test636 test637 test558 test559 test1086 test1087 test1088 \ test635 test636 test637 test558 test559 test1086 test1087 test1088 \
test1089 test1090 test1089 test1090 test1091 test1092 test1093 test1094
filecheck: filecheck:
@mkdir test-place; \ @mkdir test-place; \

46
tests/data/test1091 Normal file
View File

@ -0,0 +1,46 @@
<testcase>
# based on test 143
<info>
<keywords>
FTP
RETR
type=
</keywords>
</info>
# Server-side
<reply>
<data>
bla bla bla
</data>
</reply>
# Client-side
<client>
<server>
ftp
</server>
<name>
FTP URL with type=i
</name>
<command>
"ftp://%HOSTIP:%FTPPORT/%2ftmp/moo/1091;type=i" --use-ascii
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol>
USER anonymous
PASS ftp@example.com
PWD
CWD /tmp
CWD moo
EPSV
TYPE I
SIZE 1091
RETR 1091
QUIT
</protocol>
</verify>
</testcase>

55
tests/data/test1092 Normal file
View File

@ -0,0 +1,55 @@
<testcase>
<info>
<keywords>
FTP
HTTP
HTTP GET
HTTP proxy
</keywords>
</info>
#
# Server-side
<reply>
<data>
HTTP/1.0 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake swsclose
Content-Type: text/html
Funny-head: yesyes
contents
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
ftp
</features>
<name>
FTP over HTTP proxy
</name>
<command>
"ftp://%HOSTIP:%HTTPPORT/we/want/that/page/1092;type=i" --use-ascii -x %HOSTIP:%HTTPPORT
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/1092;type=i HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
Proxy-Connection: Keep-Alive
</protocol>
</verify>
</testcase>

44
tests/data/test1093 Normal file
View File

@ -0,0 +1,44 @@
<testcase>
<info>
<keywords>
TFTP
TFTP RRQ
mode=
</keywords>
</info>
#
# Server-side
<reply>
<data>
a chunk of
data
returned
to client
</data>
</reply>
#
# Client-side
<client>
<server>
tftp
</server>
<name>
TFTP retrieve with mode=i
</name>
<command>
"tftp://%HOSTIP:%TFTPPORT//1093;mode=i" --use-ascii --trace-ascii log/traceit
</command>
</client>
#
# Verify pseudo protocol after the test has been "shot"
<verify>
<protocol>
opcode: 1
filename: /1093
mode: octet
</protocol>
</verify>
</testcase>

50
tests/data/test1094 Normal file
View File

@ -0,0 +1,50 @@
<testcase>
<info>
<keywords>
TFTP
TFTP RRQ
mode=
</keywords>
</info>
#
# Server-side
<reply>
<data>
a chunk of
data
returned
to client
</data>
<datacheck>
a chunk of
data
returned
to client
</datacheck>
</reply>
#
# Client-side
<client>
<server>
tftp
</server>
<name>
TFTP retrieve with mode=netascii
</name>
<command>
"tftp://%HOSTIP:%TFTPPORT//1094;mode=netascii" --trace-ascii log/traceit
</command>
</client>
#
# Verify pseudo protocol after the test has been "shot"
<verify>
<protocol>
opcode: 1
filename: /1094
mode: netascii
</protocol>
</verify>
</testcase>

66
tests/data/test561 Normal file
View File

@ -0,0 +1,66 @@
<testcase>
<info>
<keywords>
FTP
HTTP proxy
CURLOPT_PROXY_TRANSFER_MODE
CURLOPT_PROXY
type=
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK swsclose
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
hello
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
ftp
</features>
<tool>
lib549
</tool>
<name>
FTP RETR with CURLOPT_PROXY_TRANSFER_MODE, ASCII transfer and type=i
</name>
# first URL then proxy
<command>
"ftp://www.haxx.se/moo/561;type=i" http://%HOSTIP:%HTTPPORT ascii
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET ftp://www.haxx.se/moo/561;type=i HTTP/1.1
Host: www.haxx.se:21
Accept: */*
Proxy-Connection: Keep-Alive
</protocol>
<stdout mode="text">
hello
</stdout>
</verify>
</testcase>