Overview
Comment: | OFURL: Implement URL-{en,de}coding of IPv6 hosts |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
c517c57c8940d2047b053abca6984336 |
User & Date: | js on 2020-03-01 23:40:28 |
Other Links: | manifest | tags |
Context
2020-03-07
| ||
18:11 | .travis.yml: Add notifications check-in: e489612993 user: js tags: trunk | |
2020-03-02
| ||
20:24 | Merge branch 'master' into 1.0 check-in: e3bbb35784 user: js tags: 1.0 | |
2020-03-01
| ||
23:40 | OFURL: Implement URL-{en,de}coding of IPv6 hosts check-in: c517c57c89 user: js tags: trunk | |
23:07 | OFURL: Add support for IPv6 / square bracket hosts check-in: a99f466e3c user: js tags: trunk | |
Changes
Modified src/OFMutableURL.m from [f41a2347d6] to [1206224cb0].
︙ | ︙ | |||
66 67 68 69 70 71 72 | } - (void)setHost: (OFString *)host { void *pool = objc_autoreleasePoolPush(); OFString *old = _URLEncodedHost; | > > > > | > | > > > > > | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | } - (void)setHost: (OFString *)host { void *pool = objc_autoreleasePoolPush(); OFString *old = _URLEncodedHost; if (of_url_is_ipv6_host(host)) _URLEncodedHost = [[OFString alloc] initWithFormat: @"[%@]", host]; else _URLEncodedHost = [[host stringByURLEncodingWithAllowedCharacters: [OFCharacterSet URLHostAllowedCharacterSet]] copy]; [old release]; objc_autoreleasePoolPop(pool); } - (void)setURLEncodedHost: (OFString *)URLEncodedHost { OFString *old; if ([URLEncodedHost hasPrefix: @"["] && [URLEncodedHost hasSuffix: @"]"]) { if (!of_url_is_ipv6_host([URLEncodedHost substringWithRange: of_range(1, URLEncodedHost.length - 2)])) @throw [OFInvalidFormatException exception]; } else if (URLEncodedHost != nil) of_url_verify_escaped(URLEncodedHost, [OFCharacterSet URLHostAllowedCharacterSet]); old = _URLEncodedHost; _URLEncodedHost = [URLEncodedHost copy]; [old release]; } |
︙ | ︙ |
Modified src/OFURL.h from [b7146fe684] to [6decb7864f].
︙ | ︙ | |||
338 339 340 341 342 343 344 345 346 347 348 | /*! * @brief Returns the characters allowed in the fragment part of a URL. * * @return The characters allowed in the fragment part of a URL. */ + (OFCharacterSet *)URLFragmentAllowedCharacterSet; @end OF_ASSUME_NONNULL_END #import "OFMutableURL.h" | > > > > > > > > | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | /*! * @brief Returns the characters allowed in the fragment part of a URL. * * @return The characters allowed in the fragment part of a URL. */ + (OFCharacterSet *)URLFragmentAllowedCharacterSet; @end #ifdef __cplusplus extern "C" { #endif extern bool of_url_is_ipv6_host(OFString *host); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END #import "OFMutableURL.h" |
Modified src/OFURL.m from [c0961c24c8] to [0cca3e3685].
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, of_unichar_t); } - (instancetype)of_initWithCharacterSet: (OFCharacterSet *)characterSet OF_METHOD_FAMILY(init); @end @implementation OFURLAllowedCharacterSetBase - (instancetype)init { OF_INVALID_INIT_METHOD } | > > > > > > > > > > > > > > > > > > > > > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, of_unichar_t); } - (instancetype)of_initWithCharacterSet: (OFCharacterSet *)characterSet OF_METHOD_FAMILY(init); @end bool of_url_is_ipv6_host(OFString *host) { const char *UTF8String = host.UTF8String; bool hasColon = false; while (*UTF8String != '\0') { if (!of_ascii_isdigit(*UTF8String) && *UTF8String != ':' && (*UTF8String < 'a' || *UTF8String > 'f') && (*UTF8String < 'A' || *UTF8String > 'F')) return false; if (*UTF8String == ':') hasColon = true; UTF8String++; } return hasColon; } @implementation OFURLAllowedCharacterSetBase - (instancetype)init { OF_INVALID_INIT_METHOD } |
︙ | ︙ | |||
827 828 829 830 831 832 833 834 835 836 837 838 839 840 | - (OFString *)URLEncodedScheme { return _URLEncodedScheme; } - (OFString *)host { return _URLEncodedHost.stringByURLDecoding; } - (OFString *)URLEncodedHost { return _URLEncodedHost; } | > > > > > > > > > > > | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 | - (OFString *)URLEncodedScheme { return _URLEncodedScheme; } - (OFString *)host { if ([_URLEncodedHost hasPrefix: @"["] && [_URLEncodedHost hasSuffix: @"]"]) { OFString *host = [_URLEncodedHost substringWithRange: of_range(1, _URLEncodedHost.length - 2)]; if (!of_url_is_ipv6_host(host)) @throw [OFInvalidArgumentException exception]; return host; } return _URLEncodedHost.stringByURLDecoding; } - (OFString *)URLEncodedHost { return _URLEncodedHost; } |
︙ | ︙ |
Modified tests/OFURLTests.m from [b020f4fabb] to [8b6c1d8b68].
︙ | ︙ | |||
150 151 152 153 154 155 156 | TEST(@"-[scheme]", [u1.scheme isEqual: @"ht:tp"] && [u4.scheme isEqual: @"file"]) TEST(@"-[user]", [u1.user isEqual: @"us:er"] && u4.user == nil) TEST(@"-[password]", [u1.password isEqual: @"p@w"] && u4.password == nil) TEST(@"-[host]", [u1.host isEqual: @"ho:st"] && | | | | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | TEST(@"-[scheme]", [u1.scheme isEqual: @"ht:tp"] && [u4.scheme isEqual: @"file"]) TEST(@"-[user]", [u1.user isEqual: @"us:er"] && u4.user == nil) TEST(@"-[password]", [u1.password isEqual: @"p@w"] && u4.password == nil) TEST(@"-[host]", [u1.host isEqual: @"ho:st"] && [u6.host isEqual: @"12:34::56:abcd"] && [u7.host isEqual: @"12:34::56:abcd"]) TEST(@"-[port]", [u1.port isEqual: [OFNumber numberWithUInt16: 1234]] && [u4 port] == nil && [u7.port isEqual: [OFNumber numberWithUInt16: 234]]) TEST(@"-[path]", [u1.path isEqual: @"/pa?th"] && [u4.path isEqual: @"/etc/passwd"]) TEST(@"-[pathComponents]", [u1.pathComponents isEqual: |
︙ | ︙ | |||
202 203 204 205 206 207 208 | (mu.URLEncodedScheme = @"ht%3Atp") && [mu.scheme isEqual: @"ht:tp"]) EXPECT_EXCEPTION( @"-[setURLEncodedScheme:] with invalid characters fails", OFInvalidFormatException, mu.URLEncodedScheme = @"~") TEST(@"-[setHost:]", | | > > > > > > | > > | | > > > > > > | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | (mu.URLEncodedScheme = @"ht%3Atp") && [mu.scheme isEqual: @"ht:tp"]) EXPECT_EXCEPTION( @"-[setURLEncodedScheme:] with invalid characters fails", OFInvalidFormatException, mu.URLEncodedScheme = @"~") TEST(@"-[setHost:]", (mu.host = @"ho:st") && [mu.URLEncodedHost isEqual: @"ho%3Ast"] && (mu.host = @"12:34:ab") && [mu.URLEncodedHost isEqual: @"[12:34:ab]"] && (mu.host = @"12:34:aB") && [mu.URLEncodedHost isEqual: @"[12:34:aB]"] && (mu.host = @"12:34:g") && [mu.URLEncodedHost isEqual: @"12%3A34%3Ag"]) TEST(@"-[setURLEncodedHost:]", (mu.URLEncodedHost = @"ho%3Ast") && [mu.host isEqual: @"ho:st"] && (mu.URLEncodedHost = @"[12:34]") && [mu.host isEqual: @"12:34"] && (mu.URLEncodedHost = @"[12::ab]") && [mu.host isEqual: @"12::ab"]) EXPECT_EXCEPTION(@"-[setURLEncodedHost:] with invalid characters fails" " #1", OFInvalidFormatException, mu.URLEncodedHost = @"/") EXPECT_EXCEPTION(@"-[setURLEncodedHost:] with invalid characters fails" " #2", OFInvalidFormatException, mu.URLEncodedHost = @"[12:34") EXPECT_EXCEPTION(@"-[setURLEncodedHost:] with invalid characters fails" " #3", OFInvalidFormatException, mu.URLEncodedHost = @"[a::g]") TEST(@"-[setUser:]", (mu.user = @"us:er") && [mu.URLEncodedUser isEqual: @"us%3Aer"]) TEST(@"-[setURLEncodedUser:]", (mu.URLEncodedUser = @"us%3Aer") && [mu.user isEqual: @"us:er"]) |
︙ | ︙ |