]> granicus.if.org Git - curl/commitdiff
Fixed a couple more locale-dependent toupper conversions, mainly for
authorDan Fandrich <dan@coneharvesters.com>
Wed, 21 Jan 2009 04:42:47 +0000 (04:42 +0000)
committerDan Fandrich <dan@coneharvesters.com>
Wed, 21 Jan 2009 04:42:47 +0000 (04:42 +0000)
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.

17 files changed:
CHANGES
RELEASE-NOTES
lib/ftp.c
lib/http.c
lib/http_ntlm.c
lib/rawstr.c
lib/rawstr.h
lib/ssluse.c
lib/tftp.c
lib/url.c
lib/url.h
tests/data/Makefile.am
tests/data/test1091 [new file with mode: 0644]
tests/data/test1092 [new file with mode: 0644]
tests/data/test1093 [new file with mode: 0644]
tests/data/test1094 [new file with mode: 0644]
tests/data/test561 [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 04123e9b0b5cecce8c9aa67ef64f637c0bd66de3..4c40fd5a0009bbcd8a7626ccdb276cda7cbdd95c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,19 @@
 
                                   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)
 - 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). 
index 55d6c8efbd09de9b75840a34ec4a1f3bb93841fd..8f29683ec83f457b09cf387e666276f4eeb3de28 100644 (file)
@@ -14,6 +14,7 @@ This release includes the following changes:
 This release includes the following bugfixes:
 
  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:
 
index 53542ecbc9e25aeac7583ca40559c8ac932d608c..66933d67342a13743d55e6d7220221122f8f6ca1 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -89,6 +89,7 @@
 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
 #include "multiif.h"
 #include "url.h"
+#include "rawstr.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -4141,7 +4142,7 @@ static CURLcode ftp_setup_connection(struct connectdata * conn)
 
   if(type) {
     *type = 0;                     /* it was in the middle of the hostname */
-    command = (char) toupper((int) type[6]);
+    command = Curl_raw_toupper(type[6]);
 
     switch (command) {
     case 'A': /* ASCII mode */
index eaa50eeef0014bf624ad70129c7129e7b8c63199..b96d51d7809b6613b79fdd045ce43f8470c9a574 100644 (file)
@@ -2271,7 +2271,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       if(checkprefix("ftp://", ppath) || checkprefix("ftps://", ppath)) {
         char *p = strstr(ppath, ";type=");
         if(p && p[6] && p[7] == 0) {
-          switch (toupper((int)((unsigned char)p[6]))) {
+          switch (Curl_raw_toupper(p[6])) {
           case 'A':
           case 'D':
           case 'I':
index afed953e25e1b3a145b359ec6a0d9b5561a6786c..869a247a0e42ad4d717d347d3107785550ff6ac3 100644 (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
  * 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_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
   * bytes are stored in the results array.
   */
-static void lm_resp(unsigned char *keys,
-                      unsigned char *plaintext,
-                      unsigned char *results)
+static void lm_resp(const unsigned char *keys,
+                    const unsigned char *plaintext,
+                    unsigned char *results)
 {
   DES_key_schedule ks;
 
@@ -377,17 +377,10 @@ static void mk_lm_hash(struct SessionHandle *data,
   static const unsigned char magic[] = {
     0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
   };
-  unsigned int i;
-  size_t len = strlen(password);
-
-  if(len > 14)
-    len = 14;
-
-  for (i=0; i<len; i++)
-    pw[i] = (unsigned char)toupper(password[i]);
+  size_t len = CURLMIN(strlen(password), 14);
 
-  for (; i<14; i++)
-    pw[i] = 0;
+  Curl_strntoupper((char *)pw, password, len);
+  memset(&pw[len], 0, 14-len);
 
 #ifdef CURL_DOES_CONVERSIONS
   /*
index b0fe38b2697fa431116cd6d4b0d28dc3609bbf79..795342338a9318222afde1ec1585e8e36aeac25e 100644 (file)
@@ -25,9 +25,9 @@
 
 #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. */
-static unsigned char my_toupper(unsigned char in)
+char Curl_raw_toupper(char in)
 {
   switch (in) {
   case 'a':
@@ -98,7 +98,7 @@ static unsigned char my_toupper(unsigned char in)
 int Curl_raw_equal(const char *first, const char *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 */
       break;
     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
      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));
+  return (Curl_raw_toupper(*first) == Curl_raw_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)) {
+    if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
       break;
     }
     max--;
@@ -123,6 +123,6 @@ int Curl_raw_nequal(const char *first, const char *second, size_t max)
   if(0 == max)
     return 1; /* they are equal this far */
 
-  return my_toupper(*first) == my_toupper(*second);
+  return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
 }
 
index 58eec77270ee9b8c0084b3f95cf248f6e38c6b52..46fb60929de0f64a727276ccdf95428b55c40a9f 100644 (file)
@@ -35,6 +35,8 @@
 int Curl_raw_equal(const char *first, const char *second);
 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
    argument is zero-byte terminated */
 #define checkprefix(a,b)    Curl_raw_nequal(a,b,strlen(a))
index 7bf549f539b9f15f66af1e10fd5a9eafae930647..ec3c53157059f4c0a587203a5acb253be803a849 100644 (file)
@@ -994,7 +994,7 @@ static int hostmatch(const char *hostname, const char *pattern)
       break;
     }
 
-    if(toupper(c) != toupper(*hostname++))
+    if(Curl_raw_toupper(c) != Curl_raw_toupper(*hostname++))
       break;
   }
   return HOST_NOMATCH;
index 4f53580fd8b69c1830fe61f9e2bbf329846dad1c..9020a1a2324353610c3b0d8b11aaf52fbe1581e4 100644 (file)
@@ -72,6 +72,7 @@
 #include "strerror.h"
 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
 #include "url.h"
+#include "rawstr.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -904,7 +905,7 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
 
   if(type) {
     *type = 0;                   /* it was in the middle of the hostname */
-    command = (char) toupper((int) type[6]);
+    command = Curl_raw_toupper(type[6]);
 
     switch (command) {
     case 'A': /* ASCII mode */
index 0145d49356d4bd6a6df60f792ad673ef572255b6..47d2af342c93cd90f078f9b130de6e6be2cb8a46 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -230,6 +230,21 @@ void Curl_safefree(void *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)
 {
   /* 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)) {
         /* There was no lowercase variable, try the uppercase version: */
-        for(envp = proxy_env; *envp; envp++)
-          *envp = (char)toupper((int)*envp);
+       Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
         prox=curl_getenv(proxy_env);
       }
 
index 2c60507c36b62910b1af7407c037fecb051e43f2..ec4da99c239abf306e4c11c432089c3aea1291ee 100644 (file)
--- a/lib/url.h
+++ b/lib/url.h
@@ -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_doing(struct connectdata *conn, bool *done);
 void Curl_safefree(void *ptr);
+void Curl_strntoupper(char *dest, const char *src, size_t n);
 
 /* create a connection cache */
 struct conncache *Curl_mk_connc(int type, long amount);
index 85a90dc959eb647ff36a8ad0860d2cec55f04926..4a459e0123686ed7bfc5868b9c7e3ac6135983e5 100644 (file)
@@ -60,7 +60,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46           \
  test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079   \
  test1080 test1081 test1082 test1083 test1084 test1085 test633 test634     \
  test635 test636 test637 test558 test559 test1086 test1087 test1088        \
- test1089 test1090
+ test1089 test1090 test1091 test1092 test1093 test1094
 
 filecheck:
        @mkdir test-place; \
diff --git a/tests/data/test1091 b/tests/data/test1091
new file mode 100644 (file)
index 0000000..f3ce860
--- /dev/null
@@ -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\r
+PASS ftp@example.com\r
+PWD\r
+CWD /tmp\r
+CWD moo\r
+EPSV\r
+TYPE I\r
+SIZE 1091\r
+RETR 1091\r
+QUIT\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1092 b/tests/data/test1092
new file mode 100644 (file)
index 0000000..26c4e05
--- /dev/null
@@ -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\r
+Host: %HOSTIP:%HTTPPORT\r
+Accept: */*\r
+Proxy-Connection: Keep-Alive\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1093 b/tests/data/test1093
new file mode 100644 (file)
index 0000000..dbcfd9f
--- /dev/null
@@ -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>
diff --git a/tests/data/test1094 b/tests/data/test1094
new file mode 100644 (file)
index 0000000..2996550
--- /dev/null
@@ -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\r
+data\r
+returned\r
+ to client\r
+</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>
diff --git a/tests/data/test561 b/tests/data/test561
new file mode 100644 (file)
index 0000000..18e827c
--- /dev/null
@@ -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\r
+Host: www.haxx.se:21\r
+Accept: */*\r
+Proxy-Connection: Keep-Alive\r
+\r
+</protocol>
+<stdout mode="text">
+hello
+</stdout>
+</verify>
+</testcase>