Reviewed by Darin
authorkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Aug 2003 20:55:50 +0000 (20:55 +0000)
committerkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Aug 2003 20:55:50 +0000 (20:55 +0000)
Fix for this bug:

<rdar://problem/3366441>: URL strings with UTF-8 characters
processed improperly for display by WebKit

        * Misc.subproj/WebNSURLExtras.h:
        * Misc.subproj/WebNSURLExtras.m:
        (isHexDigit): Added
        (hexDigitValue): Added
        (-[NSURL _web_userVisibleString]): Added. Produces a string that
is suitable for display to a user in the UI.
        (-[NSURL _web_isEmpty]): Convenience to check for an empty URL
        * WebCoreSupport.subproj/WebBridge.m:
        (-[WebBridge requestedURLString]): Now calls _web_userVisibleString

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@4816 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/ChangeLog
WebKit/Misc.subproj/WebNSURLExtras.h
WebKit/Misc.subproj/WebNSURLExtras.m
WebKit/WebCoreSupport.subproj/WebBridge.m
WebKit/WebView.subproj/WebDataSourcePrivate.m

index f98d127904b16befd7f4b570623e8f7e94d101d9..f6c1613e458499ffb51eeeb4ab35e3b474c4846a 100644 (file)
@@ -1,3 +1,22 @@
+2003-08-13  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by Darin
+
+       Fix for this bug:
+
+       <rdar://problem/3366441>: URL strings with UTF-8 characters 
+       processed improperly for display by WebKit
+
+        * Misc.subproj/WebNSURLExtras.h:
+        * Misc.subproj/WebNSURLExtras.m:
+        (isHexDigit): Added
+        (hexDigitValue): Added
+        (-[NSURL _web_userVisibleString]): Added. Produces a string that
+       is suitable for display to a user in the UI.
+        (-[NSURL _web_isEmpty]): Convenience to check for an empty URL
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge requestedURLString]): Now calls _web_userVisibleString
+
 2003-08-13  Ken Kocienda  <kocienda@apple.com>
 
         Reviewed by Darin
index 4310ce7d6bae3ddfcc459289362dc9bbab2dde66..1dd31269bbfa63a52be344ac364bfd5c20ed7124 100644 (file)
 
 - (NSData *)_web_originalData;
 
-- (NSString *)_web_displayableString;
-- (int)_web_URLStringLength;
+- (NSString *)_web_userVisibleString;
 - (const char *)_web_URLCString;
 
+- (BOOL)_web_isEmpty;
+
 // FIXME: change these names back to _web_ when identically-named
 // methods are removed from Foundation
 - (NSURL *)_webkit_canonicalize;
index 008a779d5de71065da84e9194c89b1c4bf80c95c..02353bb844ad8c235a73885e957be65d52835026 100644 (file)
@@ -24,7 +24,7 @@ static inline void ReleaseIfNotNULL(CFTypeRef object)
 
 static char hexDigit(int i) {
     if (i < 0 || i > 16) {
-        ERROR("illegal hex value");
+        ERROR("illegal hex digit");
         return '0';
     }
     int h = i;
@@ -37,6 +37,26 @@ static char hexDigit(int i) {
     return h;
 }
 
+static BOOL isHexDigit(char c)
+{
+    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
+}
+
+static int hexDigitValue(char c)
+{
+    if (c >= '0' && c <= '9') {
+        return c - '0';
+    }
+    if (c >= 'A' && c <= 'F') {
+        return c - 'A' + 10;
+    }
+    if (c >= 'a' && c <= 'f') {
+        return c - 'a' + 10;
+    }
+    ERROR("illegal hex digit");
+    return 0;
+}
+
 @implementation NSURL (WebNSURLExtras)
 
 + (NSURL *)_web_URLWithUserTypedString:(NSString *)string
@@ -156,21 +176,88 @@ static char hexDigit(int i) {
     }
 }
 
-- (NSString *)_web_displayableString
+- (NSString *)_web_userVisibleString
 {
-    return [[[NSString alloc] initWithData:[self _web_originalData] encoding:NSISOLatin1StringEncoding] autorelease];
+    NSData *data = [self _web_originalData];
+    const unsigned char *before = [data bytes];
+    int length = [data length];
+
+    const unsigned char *p = before;
+    int bufferLength = (length * 3) + 1;
+    char *after = malloc(bufferLength); // large enough to %-escape every character
+    char *q = after;
+    int i;
+    for (i = 0; i < length; i++) {
+        unsigned char c = p[i];
+        // escape control characters, space, and delete
+        if (c <= 0x20 || c == 0x7f) {
+            *q++ = '%';
+            *q++ = hexDigit(c >> 4);
+            *q++ = hexDigit(c & 0xf);
+        }
+        // unescape escape sequences that indicate bytes greater than 0x7f
+        else if (c == '%' && (i + 1 < length && isHexDigit(p[i + 1])) && i + 2 < length && isHexDigit(p[i + 2])) {
+            unsigned char u = (hexDigitValue(p[i + 1]) << 4) | hexDigitValue(p[i + 2]);
+            if (u > 0x7f) {
+                // unescape
+                *q++ = u;
+            }
+            else {
+                // do not unescape
+                *q++ = p[i];
+                *q++ = p[i + 1];
+                *q++ = p[i + 2];
+            }
+            i += 2;
+        } 
+        else {
+            *q++ = c;
+        }
+    }
+    *q = '\0';
+  
+    // Check string to see if it can be converted to display using UTF-8  
+    NSString *result = [NSString stringWithUTF8String:after];
+    if (!result) {
+        // Could not convert to UTF-8.
+        // Convert characters greater than 0x7f to escape sequences.
+        // Shift current string to the end of the buffer
+        // then we will copy back bytes to the start of the buffer 
+        // as we convert.
+        int afterlength = q - after;
+        char *p = after + bufferLength - afterlength - 1;
+        memmove(p, after, afterlength + 1); // copies trailing '\0'
+        char *q = after;
+        while (*p) {
+            unsigned char c = *p;
+            if (c > 0x7f) {
+                *q++ = '%';
+                *q++ = hexDigit(c >> 4);
+                *q++ = hexDigit(c & 0xf);
+            }
+            else {
+                *q++ = *p;
+            }
+            p++;
+        }
+        *q = '\0';
+        result = [NSString stringWithUTF8String:after];
+    }
+    free(after);
+    
+    return result;
 }
 
-- (int)_web_URLStringLength
+- (BOOL)_web_isEmpty
 {
     int length = 0;
     if (!CFURLGetBaseURL((CFURLRef)self)) {
         length = CFURLGetBytes((CFURLRef)self, NULL, 0);
     }
     else {
-        length = [[self _web_displayableString] length];
+        length = [[self _web_userVisibleString] length];
     }
-    return length;
+    return length == 0;
 }
 
 - (const char *)_web_URLCString
@@ -240,26 +327,6 @@ static char hexDigit(int i) {
 
 @implementation NSString (WebNSURLExtras)
 
-static BOOL isHexDigit(char c)
-{
-    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
-}
-
-static int hexDigitValue(char c)
-{
-    if (c >= '0' && c <= '9') {
-        return c - '0';
-    }
-    if (c >= 'A' && c <= 'F') {
-        return c - 'A' + 10;
-    }
-    if (c >= 'a' && c <= 'f') {
-        return c - 'a' + 10;
-    }
-    ERROR("illegal hex digit");
-    return 0;
-}
-
 - (BOOL)_webkit_isJavaScriptURL
 {
     return [self _web_hasCaseInsensitivePrefix:@"javascript:"];
index a6ffb29e8a444b6043c13452ae5a83eba5d96467..26a2f6a64f594b11db7d9354f1ee640d6ac68b9b 100644 (file)
 
     NSMutableURLRequest *request = nil;
 
-    if (URL != nil && [URL _web_URLStringLength] > 0) {
+    if (URL != nil && ![URL _web_isEmpty]) {
        request = [NSMutableURLRequest requestWithURL:URL];
        [request setHTTPReferrer:[self referrer]];
     }
 // This URL is only used for coloring visited links.
 - (NSString *)requestedURLString
 {
-    return [[[[self dataSource] request] URL] _web_displayableString];
+    return [[[[self dataSource] request] URL] _web_userVisibleString];
 }
 
 - (NSString *)incomingReferrer
 
     if (errorCode) {
         NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
-                                                  contentURLString:[URL _web_displayableString]
+                                                  contentURLString:[URL _web_userVisibleString]
                                                pluginPageURLString:[attributes objectForKey:@"pluginspage"]
                                                         pluginName:[pluginPackage name]
                                                           MIMEType:MIMEType];
index 0079b2eebdabe8285499b05f2ad882e43bd69c77..6b7a6b586835d62210efae5a374d8c72464c461f 100644 (file)
             
         // WebCore will crash if given an empty URL here.
         // FIXME: could use CFURL, when available, range API to save an allocation here
-        if (!URL || [URL _web_URLStringLength] == 0)
+        if (!URL || [URL _web_isEmpty])
             URL = [NSURL URLWithString:@"about:blank"];
 
         [[self _bridge] openURL:URL