Ticket #12710: 0001-BPackageInfo-Parser-Validate-URL-strings.patch
File 0001-BPackageInfo-Parser-Validate-URL-strings.patch, 29.1 KB (added by , 8 years ago) |
---|
-
.gitignore
From 4d703fb78008e98867091ed641e2e1e60a7b117c Mon Sep 17 00:00:00 2001 From: Andrew Lindesay <apl@lindesay.co.nz> Date: Sat, 9 Apr 2016 18:49:29 +1200 Subject: [PATCH] BPackageInfo::Parser: Validate URL strings. --- .gitignore | 3 + build/jam/BuildSetup | 4 +- headers/os/net/Url.h | 25 ++- src/bin/Jamfile | 7 +- src/build/libbe/Jamfile | 4 + src/build/libbe/network/Jamfile | 15 ++ src/build/libgnuregex/Jamfile | 6 +- src/build/libgnuregex/ReadMe.md | 12 + src/build/libpackage/Jamfile | 2 + src/build/libshared/Jamfile | 7 + src/kits/network/libnetapi/Url.cpp | 96 +++++--- src/kits/package/Jamfile | 2 + src/kits/package/PackageInfoParser.cpp | 39 +++- src/kits/package/PackageInfoParser.h | 19 +- src/tests/kits/net/libnetapi/Jamfile | 1 + src/tests/kits/net/libnetapi/NetAPITestAddon.cpp | 2 + src/tests/kits/net/libnetapi/NetworkUrlTest.cpp | 272 +++++++++++++++++++++++ src/tests/kits/net/libnetapi/NetworkUrlTest.h | 42 ++++ 18 files changed, 506 insertions(+), 52 deletions(-) create mode 100644 src/build/libbe/network/Jamfile create mode 100644 src/build/libgnuregex/ReadMe.md create mode 100644 src/tests/kits/net/libnetapi/NetworkUrlTest.cpp create mode 100644 src/tests/kits/net/libnetapi/NetworkUrlTest.h diff --git a/.gitignore b/.gitignore index 9e9420d..96542f4 100644
a b conf.sh 12 12 # compiled/optimized Python 13 13 *.pyc 14 14 *.pyo 15 16 # MacOS-X directory attributes 17 .DS_Store -
build/jam/BuildSetup
diff --git a/build/jam/BuildSetup b/build/jam/BuildSetup index d13922a..801c27f 100644
a b if $(HOST_PLATFORM_BEOS_COMPATIBLE) { 496 496 HOST_LIBROOT += /usr/lib/libgnuregex.so ; 497 497 HOST_STATIC_LIBROOT += /usr/lib/libgnuregex.so ; 498 498 } else if $(HOST_PLATFORM) = darwin { 499 HOST_LIBROOT += libgnuregex_build. a;500 HOST_STATIC_LIBROOT += libgnuregex_build. a;499 HOST_LIBROOT += libgnuregex_build.so ; 500 HOST_STATIC_LIBROOT += libgnuregex_build.so ; 501 501 } 502 502 503 503 # The BeOS compilers define __INTEL__ respectively __POWERPC__. On the -
headers/os/net/Url.h
diff --git a/headers/os/net/Url.h b/headers/os/net/Url.h index da241cc..560e08b 100644
a b 1 1 /* 2 * Copyright 2010 Haiku Inc. All rights reserved.2 * Copyright 2010-2016 Haiku Inc. All rights reserved. 3 3 * Distributed under the terms of the MIT License. 4 4 */ 5 5 #ifndef _B_URL_H_ … … public: 33 33 BUrl& SetPath(const BString& path); 34 34 BUrl& SetRequest(const BString& request); 35 35 BUrl& SetFragment(const BString& fragment); 36 36 37 37 // URL fields access 38 38 const BString& UrlString() const; 39 39 const BString& Protocol() const; … … public: 46 46 const BString& Path() const; 47 47 const BString& Request() const; 48 48 const BString& Fragment() const; 49 49 50 50 // URL fields tests 51 51 bool IsValid() const; 52 52 bool HasProtocol() const; … … public: 64 64 void UrlEncode(bool strict = false); 65 65 void UrlDecode(bool strict = false); 66 66 67 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 67 68 status_t IDNAToAscii(); 68 69 status_t IDNAToUnicode(); 70 #endif 69 71 70 72 // Url encoding/decoding of strings 71 static BString UrlEncode(const BString& url, 72 bool strict = false, 73 static BString UrlEncode(const BString& url, 74 bool strict = false, 73 75 bool directory = false); 74 static BString UrlDecode(const BString& url, 76 static BString UrlDecode(const BString& url, 75 77 bool strict = false); 76 78 79 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 77 80 // utility functionality 78 81 bool HasPreferredApplication() const; 79 82 BString PreferredApplication() const; 80 83 status_t OpenWithPreferredApplication( 81 84 bool onProblemAskUser = true) const; 85 #endif 82 86 83 87 // BArchivable members 84 88 virtual status_t Archive(BMessage* into, … … public: 93 97 const BUrl& operator=(const BUrl& other); 94 98 const BUrl& operator=(const BString& string); 95 99 const BUrl& operator=(const char* string); 96 100 97 101 // URL to string conversion 98 102 operator const char*() const; 99 103 100 104 private: 101 105 void _ResetFields(); 106 bool _ContainsDelimiter(const BString& url); 102 107 void _ExplodeUrlString(const BString& urlString); 103 108 BString _MergePath(const BString& relative) const; 104 109 void _SetPathUnsafe(const BString& path); 105 110 106 static BString _DoUrlEncodeChunk(const BString& chunk, 111 static BString _DoUrlEncodeChunk(const BString& chunk, 107 112 bool strict, bool directory = false); 108 static BString _DoUrlDecodeChunk(const BString& chunk, 113 static BString _DoUrlDecodeChunk(const BString& chunk, 109 114 bool strict); 110 115 111 116 bool _IsProtocolValid(); … … private: 128 133 BString fPath; 129 134 BString fRequest; 130 135 BString fFragment; 131 136 132 137 mutable bool fUrlStringValid : 1; 133 138 mutable bool fAuthorityValid : 1; 134 139 mutable bool fUserInfoValid : 1; -
src/bin/Jamfile
diff --git a/src/bin/Jamfile b/src/bin/Jamfile index de947dc..8b20291 100644
a b StdBinCommands 134 134 ramdisk.cpp 135 135 : shared be [ TargetLibsupc++ ] : $(haiku-utils_rsrc) ; 136 136 137 # standard commands that need libbe.so, libbnetapi.solibsupc++.so 137 # standard commands that need libbe.so, libbnetapi.so 138 StdBinCommands 139 package.cpp 140 : be bnetapi : $(haiku-utils_rsrc) ; 141 142 # standard commands that need libbe.so, libbnetapi.so, libsupc++.so 138 143 StdBinCommands 139 144 open.cpp 140 145 urlwrapper.cpp -
src/build/libbe/Jamfile
diff --git a/src/build/libbe/Jamfile b/src/build/libbe/Jamfile index 70f487e..0429a29 100644
a b BuildPlatformSharedLibrary libbe_build.so : 11 11 <libbe_build>app_kit.o 12 12 <libbe_build>icon_kit.o 13 13 <libbe_build>interface_kit.o 14 <libbe_build>network_kit.o 14 15 <libbe_build>storage_kit.o 15 16 <libbe_build>support_kit.o 16 17 18 libshared_build.a 19 17 20 z $(HOST_LIBSUPC++) $(HOST_LIBSTDC++) 18 21 ; 19 22 20 23 SubInclude HAIKU_TOP src build libbe app ; 21 24 SubInclude HAIKU_TOP src build libbe icon ; 22 25 SubInclude HAIKU_TOP src build libbe interface ; 26 SubInclude HAIKU_TOP src build libbe network ; 23 27 SubInclude HAIKU_TOP src build libbe storage ; 24 28 SubInclude HAIKU_TOP src build libbe support ; -
new file src/build/libbe/network/Jamfile
diff --git a/src/build/libbe/network/Jamfile b/src/build/libbe/network/Jamfile new file mode 100644 index 0000000..c824cec
- + 1 SubDir HAIKU_TOP src build libbe network; 2 3 UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ; 4 UseHeaders [ FDirName $(HAIKU_TOP) headers os net ] : true ; 5 UseHeaders [ FDirName $(HAIKU_TOP) headers private shared ] : true ; 6 7 UsePrivateBuildHeaders app interface shared network ; 8 9 USES_BE_API on <libbe_build>network_kit.o = true ; 10 11 SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits network libnetapi ] ; 12 13 BuildPlatformMergeObjectPIC <libbe_build>network_kit.o : 14 Url.cpp 15 ; -
src/build/libgnuregex/Jamfile
diff --git a/src/build/libgnuregex/Jamfile b/src/build/libgnuregex/Jamfile index 6f3d05b..cfcc8ef 100644
a b 1 1 SubDir HAIKU_TOP src build libgnuregex ; 2 2 3 BuildPlatformStaticLibrary libgnuregex_build.a : regex.c ; 3 BuildPlatformSharedLibrary libgnuregex_build.so : 4 regex.c 5 : 6 # no linked libraries here 7 ; -
new file src/build/libgnuregex/ReadMe.md
diff --git a/src/build/libgnuregex/ReadMe.md b/src/build/libgnuregex/ReadMe.md new file mode 100644 index 0000000..7dadd29
- + 1 # libgnuregex 2 3 This library exists because some systems don't have a flavor of regex library 4 built-in which supports groups. This variant does include group-support. An 5 example of where this comes into play is with the `BUrl` class where URLs are 6 parsed, in part, using regular expressions. 7 8 ## Use with MacOS-X 9 10 In the case of MacOS-X, the dynamic-library build product 11 `libgnuregex_build.so` can be configured for use by configuring the 12 `DYLD_INSERT_LIBRARIES` environment variable. -
src/build/libpackage/Jamfile
diff --git a/src/build/libpackage/Jamfile b/src/build/libpackage/Jamfile index fa1b4e2..83cfa8b 100644
a b SubDir HAIKU_TOP src build libpackage ; 2 2 3 3 UsePrivateBuildHeaders kernel package shared storage support ; 4 4 5 UseHeaders [ FDirName $(HAIKU_TOP) headers os net ] : true ; 6 5 7 SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package ] ; 6 8 SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg ] ; 7 9 SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg v1 ] ; -
src/build/libshared/Jamfile
diff --git a/src/build/libshared/Jamfile b/src/build/libshared/Jamfile index 44984b7..3999b00 100644
a b SubDir HAIKU_TOP src build libshared ; 2 2 3 3 USES_BE_API on libshared_build.a = true ; 4 4 5 UseHeaders [ FDirName $(HAIKU_TOP) headers private shared ] : true ; 6 5 7 UsePrivateBuildHeaders shared ; 6 8 7 9 SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits shared ] ; … … BuildPlatformStaticLibraryPIC libshared_build.a : 10 12 Keymap.cpp 11 13 NaturalCompare.cpp 12 14 SHA256.cpp 15 RegExp.cpp 16 17 : 18 19 # no shared libs, but will require 'libgnuregex' dynamic library on Darwin 13 20 ; -
src/kits/network/libnetapi/Url.cpp
diff --git a/src/kits/network/libnetapi/Url.cpp b/src/kits/network/libnetapi/Url.cpp index e68b535..418a3a2 100644
a b 1 1 /* 2 * Copyright 2010 Haiku Inc. All rights reserved.2 * Copyright 2010-2016 Haiku Inc. All rights reserved. 3 3 * Distributed under the terms of the MIT License. 4 4 * 5 5 * Authors: 6 6 * Christophe Huriaux, c.huriaux@gmail.com 7 * Andrew Lindesay, apl@lindesay.co.nz 7 8 */ 8 9 9 10 … … 17 18 #include <MimeType.h> 18 19 #include <Roster.h> 19 20 21 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 20 22 #include <ICUWrapper.h> 23 #endif 21 24 #include <RegExp.h> 22 25 26 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 23 27 #include <unicode/idna.h> 24 28 #include <unicode/stringpiece.h> 29 #endif 25 30 26 31 27 32 static const char* kArchivedUrl = "be:url string"; … … BUrl::Fragment() const 498 503 bool 499 504 BUrl::IsValid() const 500 505 { 506 if (!fHasProtocol) 507 return false; 508 509 if (fProtocol == "http" || fProtocol == "https" || fProtocol == "ftp") 510 return fHasHost; 511 501 512 // TODO: Implement for real! 502 return fHasProtocol &&(fHasHost || fHasPath);513 return (fHasHost || fHasPath); 503 514 } 504 515 505 516 … … BUrl::UrlDecode(bool strict) 598 609 } 599 610 600 611 612 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 601 613 status_t 602 614 BUrl::IDNAToAscii() 603 615 { … … BUrl::IDNAToAscii() 618 630 fHost = result; 619 631 return B_OK; 620 632 } 633 #endif 621 634 622 635 636 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 623 637 status_t 624 638 BUrl::IDNAToUnicode() 625 639 { … … BUrl::IDNAToUnicode() 640 654 fHost = result; 641 655 return B_OK; 642 656 } 657 #endif 643 658 644 659 645 660 // #pragma mark - utility functionality 646 661 647 662 663 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 648 664 bool 649 665 BUrl::HasPreferredApplication() const 650 666 { … … BUrl::HasPreferredApplication() const 657 673 658 674 return false; 659 675 } 676 #endif 660 677 661 678 679 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 662 680 BString 663 681 BUrl::PreferredApplication() const 664 682 { … … BUrl::PreferredApplication() const 669 687 670 688 return BString(appSignature); 671 689 } 690 #endif 672 691 673 692 693 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 674 694 status_t 675 695 BUrl::OpenWithPreferredApplication(bool onProblemAskUser) const 676 696 { … … BUrl::OpenWithPreferredApplication(bool onProblemAskUser) const 710 730 711 731 return status; 712 732 } 733 #endif 713 734 714 735 715 736 // #pragma mark Url encoding/decoding of string … … BUrl::_ResetFields() 866 887 } 867 888 868 889 890 bool 891 BUrl::_ContainsDelimiter(const BString& url) 892 { 893 int32 len = url.Length(); 894 895 for (int32 i=0; i < len; i++) { 896 switch (url[i]) { 897 case ' ': 898 case '\n': 899 case '\t': 900 case '\r': 901 case '<': 902 case '>': 903 case '"': 904 return true; 905 } 906 } 907 908 return false; 909 } 910 911 869 912 void 870 913 BUrl::_ExplodeUrlString(const BString& url) 871 914 { … … BUrl::_ExplodeUrlString(const BString& url) 875 918 876 919 _ResetFields(); 877 920 921 // RFC3986, Appendix C; the URL should not contain whitespace or delimiters 922 // by this point. 923 if (_ContainsDelimiter(url)) 924 return; // TODO error handing 925 878 926 RegExp::MatchResult match = urlMatcher.Match(url.String()); 879 927 880 928 if (!match.HasMatched()) … … BUrl::_ExplodeUrlString(const BString& url) 883 931 // Scheme/Protocol 884 932 url.CopyInto(fProtocol, match.GroupStartOffsetAt(1), 885 933 match.GroupEndOffsetAt(1) - match.GroupStartOffsetAt(1)); 934 886 935 if (!_IsProtocolValid()) { 887 936 fHasProtocol = false; 888 937 fProtocol.Truncate(0); … … BUrl::SetAuthority(const BString& authority) 981 1030 return; 982 1031 983 1032 int32 userInfoEnd = fAuthority.FindFirst('@'); 1033 int16 hostAndPortStart = 0; 984 1034 985 1035 // URL contains userinfo field 986 1036 if (userInfoEnd != -1) { … … BUrl::SetAuthority(const BString& authority) 1000 1050 } else { 1001 1051 SetUserName(fUser); 1002 1052 } 1003 }1004 1005 1053 1006 // Extract the host part 1007 int16 hostEnd = fAuthority.FindFirst(':', userInfoEnd); 1008 userInfoEnd++; 1009 1010 if (hostEnd < 0) { 1011 // no ':' found, the host extends to the end of the URL 1012 hostEnd = fAuthority.Length() + 1; 1054 hostAndPortStart = userInfoEnd + 1; 1013 1055 } 1014 1056 1015 // The host is likely to be present if an authority is 1016 // defined, but in some weird cases, it's not. 1017 if (hostEnd != userInfoEnd) { 1018 fAuthority.CopyInto(fHost, userInfoEnd, hostEnd - userInfoEnd); 1019 SetHost(fHost); 1020 } 1057 int16 hostEnd = fAuthority.FindFirst(':', hostAndPortStart); 1021 1058 1022 // Extract the port part 1023 fPort = 0; 1024 if (fAuthority.ByteAt(hostEnd) == ':') { 1025 hostEnd++; 1026 int16 portEnd = fAuthority.Length(); 1027 1028 BString portString; 1029 fAuthority.CopyInto(portString, hostEnd, portEnd - hostEnd); 1030 fPort = atoi(portString.String()); 1031 1032 // Even if the port is invalid, the URL is considered to 1033 // have a port. 1034 fHasPort = portString.Length() > 0; 1059 if (hostEnd != B_ERROR) { 1060 if (hostEnd < fAuthority.Length()-1) { 1061 fPort = atoi(&(fAuthority.String())[hostEnd+1]); 1062 fHasPort = true; 1063 } 1035 1064 } 1065 else 1066 hostEnd = fAuthority.Length(); 1067 1068 fAuthority.CopyInto(fHost, hostAndPortStart, hostEnd - hostAndPortStart); 1069 SetHost(fHost); 1036 1070 } 1037 1071 1038 1072 … … BUrl::_DoUrlDecodeChunk(const BString& chunk, bool strict) 1088 1122 result << decoded; 1089 1123 } else 1090 1124 result << chunk[i]; 1091 } 1125 } 1092 1126 } 1093 1127 return result; 1094 1128 } -
src/kits/package/Jamfile
diff --git a/src/kits/package/Jamfile b/src/kits/package/Jamfile index 013c9ee..7d221f2 100644
a b for architectureObject in [ MultiArchSubDirSetup ] { 129 129 SolverResult.cpp 130 130 : 131 131 shared 132 bnetapi 132 133 be 133 134 [ BuildFeatureAttribute curl : library ] 134 135 [ TargetLibstdc++ ] 136 $(TARGET_NETWORK_LIBS) 135 137 ; 136 138 } 137 139 } -
src/kits/package/PackageInfoParser.cpp
diff --git a/src/kits/package/PackageInfoParser.cpp b/src/kits/package/PackageInfoParser.cpp index f684815..3de3a7c 100644
a b 1 1 /* 2 2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de> 3 * Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz> 3 4 * Distributed under the terms of the MIT License. 4 5 */ 5 6 … … 13 14 #include <algorithm> 14 15 #include <string> 15 16 17 #include <Url.h> 16 18 17 19 namespace BPackageKit { 18 20 … … BPackageInfo::Parser::_ParseList(ListElementParser& elementParser, 508 510 509 511 void 510 512 BPackageInfo::Parser::_ParseStringList(BStringList* value, 511 bool requireResolvableName, bool convertToLowerCase) 513 bool requireResolvableName, bool convertToLowerCase, 514 StringValidator* stringValidator) 512 515 { 513 516 struct StringParser : public ListElementParser { 514 517 BStringList* value; 515 518 bool requireResolvableName; 516 519 bool convertToLowerCase; 520 StringValidator* stringValidator; 517 521 518 522 StringParser(BStringList* value, bool requireResolvableName, 519 bool convertToLowerCase )523 bool convertToLowerCase, StringValidator* stringValidator) 520 524 : 521 525 value(value), 522 526 requireResolvableName(requireResolvableName), 523 convertToLowerCase(convertToLowerCase) 527 convertToLowerCase(convertToLowerCase), 528 stringValidator(stringValidator) 524 529 { 525 530 } 526 531 … … BPackageInfo::Parser::_ParseStringList(BStringList* value, 541 546 if (convertToLowerCase) 542 547 element.ToLower(); 543 548 549 if (stringValidator != NULL) 550 stringValidator->Validate(element, token.pos); 551 544 552 value->Add(element); 545 553 } 546 } stringParser(value, requireResolvableName, convertToLowerCase); 554 } stringParser(value, requireResolvableName, convertToLowerCase, 555 stringValidator); 547 556 548 557 _ParseList(stringParser, true); 549 558 } … … BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) 1008 1017 break; 1009 1018 1010 1019 case B_PACKAGE_INFO_URLS: 1011 _ParseStringList(&packageInfo->fURLList); 1020 { 1021 UrlStringValidator stringValidator; 1022 _ParseStringList(&packageInfo->fURLList, 1023 false, false, &stringValidator); 1024 } 1012 1025 break; 1013 1026 1014 1027 case B_PACKAGE_INFO_SOURCE_URLS: 1015 _ParseStringList(&packageInfo->fSourceURLList); 1028 { 1029 UrlStringValidator stringValidator; 1030 _ParseStringList(&packageInfo->fSourceURLList, 1031 false, false, &stringValidator); 1032 } 1016 1033 break; 1017 1034 1018 1035 case B_PACKAGE_INFO_GLOBAL_WRITABLE_FILES: … … BPackageInfo::Parser::_IsValidResolvableName(const char* string, 1145 1162 return true; 1146 1163 } 1147 1164 1165 void 1166 BPackageInfo::Parser::UrlStringValidator::Validate(const BString& urlString, 1167 const char* pos) 1168 { 1169 BUrl url(urlString); 1170 1171 if (!url.IsValid()) 1172 throw ParseError("invalid url", pos); 1173 } 1174 1148 1175 1149 1176 } // namespace BPackageKit -
src/kits/package/PackageInfoParser.h
diff --git a/src/kits/package/PackageInfoParser.h b/src/kits/package/PackageInfoParser.h index 6824b9e..5319558 100644
a b 1 1 /* 2 2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de> 3 * Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz> 3 4 * Distributed under the terms of the MIT License. 4 5 */ 5 6 #ifndef PACKAGE_INFO_PARSER_H … … public: 31 32 BPackageResolvableExpression& _expression); 32 33 33 34 private: 35 struct UrlStringValidator; 36 struct StringValidator; 34 37 struct ParseError; 35 38 struct Token; 36 39 struct ListElementParser; … … private: 74 77 bool allowSingleNonListElement); 75 78 void _ParseStringList(BStringList* value, 76 79 bool requireResolvableName = false, 77 bool convertToLowerCase = false); 80 bool convertToLowerCase = false, 81 StringValidator* stringValidator = NULL); 78 82 void _ParseResolvableList( 79 83 BObjectList<BPackageResolvable>* value); 80 84 void _ParseResolvableExprList( … … struct BPackageInfo::Parser::ListElementParser { 152 156 }; 153 157 154 158 159 struct BPackageInfo::Parser::StringValidator { 160 public: 161 virtual void Validate(const BString &string, const char *pos) = 0; 162 }; 163 164 165 struct BPackageInfo::Parser::UrlStringValidator 166 : public BPackageInfo::Parser::StringValidator { 167 public: 168 virtual void Validate(const BString &string, const char* pos); 169 }; 170 171 155 172 } // namespace BPackageKit 156 173 157 174 -
src/tests/kits/net/libnetapi/Jamfile
diff --git a/src/tests/kits/net/libnetapi/Jamfile b/src/tests/kits/net/libnetapi/Jamfile index b2e34ce..6a7d8fa 100644
a b UnitTestLib libnetapitest.so : 5 5 6 6 NetworkAddressTest.cpp 7 7 NetworkInterfaceTest.cpp 8 NetworkUrlTest.cpp 8 9 9 10 : be bnetapi network [ TargetLibstdc++ ] [ TargetLibsupc++ ] 10 11 ; -
src/tests/kits/net/libnetapi/NetAPITestAddon.cpp
diff --git a/src/tests/kits/net/libnetapi/NetAPITestAddon.cpp b/src/tests/kits/net/libnetapi/NetAPITestAddon.cpp index 593ab4a..fd9e398 100644
a b 9 9 10 10 #include "NetworkAddressTest.h" 11 11 #include "NetworkInterfaceTest.h" 12 #include "NetworkUrlTest.h" 12 13 13 14 14 15 BTestSuite* … … getTestSuite() 18 19 19 20 NetworkAddressTest::AddTests(*suite); 20 21 NetworkInterfaceTest::AddTests(*suite); 22 NetworkUrlTest::AddTests(*suite); 21 23 22 24 return suite; 23 25 } -
new file src/tests/kits/net/libnetapi/NetworkUrlTest.cpp
diff --git a/src/tests/kits/net/libnetapi/NetworkUrlTest.cpp b/src/tests/kits/net/libnetapi/NetworkUrlTest.cpp new file mode 100644 index 0000000..23feb96
- + 1 /* 2 * Copyright 2016, Andrew Lindesay, apl@lindesay.co.nz. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "NetworkUrlTest.h" 8 9 #include <Url.h> 10 11 #include <cppunit/TestCaller.h> 12 #include <cppunit/TestSuite.h> 13 14 15 NetworkUrlTest::NetworkUrlTest() 16 { 17 } 18 19 20 NetworkUrlTest::~NetworkUrlTest() 21 { 22 } 23 24 25 void 26 NetworkUrlTest::setUp() 27 { 28 } 29 30 31 void 32 NetworkUrlTest::tearDown() 33 { 34 } 35 36 37 // General Tests --------------------------------------------------------------- 38 39 /* 40 This is the "happy days" tests that checks that a URL featuring all of the 41 parsed elements successfully processes and the elements are present. 42 */ 43 44 void NetworkUrlTest::TestValidFullUrl() 45 { 46 BUrl url("http://ewe:pea@www.something.co.nz:8888/some/path?key1=value1#fragment"); 47 CPPUNIT_ASSERT(url.IsValid()); 48 CPPUNIT_ASSERT(url.Protocol() == "http"); 49 CPPUNIT_ASSERT(url.HasProtocol()); 50 CPPUNIT_ASSERT(url.UserName() == "ewe"); 51 CPPUNIT_ASSERT(url.HasUserName()); 52 CPPUNIT_ASSERT(url.Password() == "pea"); 53 CPPUNIT_ASSERT(url.HasPassword()); 54 CPPUNIT_ASSERT(url.Host() == "www.something.co.nz"); 55 CPPUNIT_ASSERT(url.HasHost()); 56 CPPUNIT_ASSERT(url.Port() == 8888); 57 CPPUNIT_ASSERT(url.HasPort()); 58 CPPUNIT_ASSERT(url.Path() == "/some/path"); 59 CPPUNIT_ASSERT(url.HasPath()); 60 CPPUNIT_ASSERT(url.Request() == "key1=value1"); 61 CPPUNIT_ASSERT(url.HasRequest()); 62 CPPUNIT_ASSERT(url.Fragment() == "fragment"); 63 CPPUNIT_ASSERT(url.HasFragment()); 64 } 65 66 67 void NetworkUrlTest::TestFileUrl() 68 { 69 BUrl url("file:///northisland/wellington/brooklyn/windturbine"); 70 CPPUNIT_ASSERT(url.IsValid()); 71 CPPUNIT_ASSERT(url.Protocol() == "file"); 72 CPPUNIT_ASSERT(url.HasProtocol()); 73 CPPUNIT_ASSERT(!url.HasUserName()); 74 CPPUNIT_ASSERT(!url.HasPassword()); 75 CPPUNIT_ASSERT(url.Host() == ""); 76 CPPUNIT_ASSERT(url.HasHost()); 77 CPPUNIT_ASSERT(!url.HasPort()); 78 CPPUNIT_ASSERT(url.Path() == "/northisland/wellington/brooklyn/windturbine"); 79 CPPUNIT_ASSERT(url.HasPath()); 80 CPPUNIT_ASSERT(!url.HasRequest()); 81 CPPUNIT_ASSERT(!url.HasFragment()); 82 } 83 84 85 // Authority Tests (UserName, Password, Host, Port) ---------------------------- 86 87 88 void NetworkUrlTest::TestWithUserNameAndPasswordNoHostAndPort() 89 { 90 BUrl url("wierd://tea:tree@/x"); 91 CPPUNIT_ASSERT(url.IsValid()); 92 CPPUNIT_ASSERT(url.Protocol() == "wierd"); 93 CPPUNIT_ASSERT(url.HasProtocol()); 94 CPPUNIT_ASSERT(url.UserName() == "tea"); 95 CPPUNIT_ASSERT(url.HasUserName()); 96 CPPUNIT_ASSERT(url.Password() == "tree"); 97 CPPUNIT_ASSERT(url.HasPassword()); 98 CPPUNIT_ASSERT(url.Host() == ""); 99 CPPUNIT_ASSERT(!url.HasHost()); 100 CPPUNIT_ASSERT(!url.HasPort()); 101 CPPUNIT_ASSERT(url.Path() == "/x"); 102 CPPUNIT_ASSERT(url.HasPath()); 103 CPPUNIT_ASSERT(!url.HasRequest()); 104 CPPUNIT_ASSERT(!url.HasFragment()); 105 } 106 107 108 void NetworkUrlTest::TestHostAndPortWithNoUserNameAndPassword() 109 { 110 BUrl url("https://www.something.co.nz:443/z"); 111 CPPUNIT_ASSERT(url.IsValid()); 112 CPPUNIT_ASSERT(url.Protocol() == "https"); 113 CPPUNIT_ASSERT(url.HasProtocol()); 114 CPPUNIT_ASSERT(!url.HasUserName()); 115 CPPUNIT_ASSERT(!url.HasPassword()); 116 CPPUNIT_ASSERT(url.Port() == 443); 117 CPPUNIT_ASSERT(url.HasPort()); 118 CPPUNIT_ASSERT(url.Host() == "www.something.co.nz"); 119 CPPUNIT_ASSERT(url.HasHost()); 120 CPPUNIT_ASSERT(url.Path() == "/z"); 121 CPPUNIT_ASSERT(url.HasPath()); 122 CPPUNIT_ASSERT(!url.HasRequest()); 123 CPPUNIT_ASSERT(!url.HasFragment()); 124 } 125 126 127 void NetworkUrlTest::TestHostWithNoPortOrUserNameAndPassword() 128 { 129 BUrl url("https://www.something.co.nz/z"); 130 CPPUNIT_ASSERT(url.IsValid()); 131 CPPUNIT_ASSERT(url.Protocol() == "https"); 132 CPPUNIT_ASSERT(url.HasProtocol()); 133 CPPUNIT_ASSERT(!url.HasUserName()); 134 CPPUNIT_ASSERT(!url.HasPassword()); 135 CPPUNIT_ASSERT(url.Host() == "www.something.co.nz"); 136 CPPUNIT_ASSERT(url.HasHost()); 137 CPPUNIT_ASSERT(!url.HasPort()); 138 CPPUNIT_ASSERT(url.Path() == "/z"); 139 CPPUNIT_ASSERT(url.HasPath()); 140 CPPUNIT_ASSERT(!url.HasRequest()); 141 CPPUNIT_ASSERT(!url.HasFragment()); 142 } 143 144 145 void NetworkUrlTest::TestHostWithNoPortNoPath() 146 { 147 BUrl url("https://www.something.co.nz"); 148 CPPUNIT_ASSERT(url.IsValid()); 149 CPPUNIT_ASSERT(url.Protocol() == "https"); 150 CPPUNIT_ASSERT(url.HasProtocol()); 151 CPPUNIT_ASSERT(!url.HasUserName()); 152 CPPUNIT_ASSERT(!url.HasPassword()); 153 CPPUNIT_ASSERT(url.Host() == "www.something.co.nz"); 154 CPPUNIT_ASSERT(url.HasHost()); 155 CPPUNIT_ASSERT(!url.HasPort()); 156 CPPUNIT_ASSERT(!url.HasPath()); 157 CPPUNIT_ASSERT(!url.HasRequest()); 158 CPPUNIT_ASSERT(!url.HasFragment()); 159 } 160 161 162 void NetworkUrlTest::TestHostWithPortNoPath() 163 { 164 BUrl url("https://www.something.co.nz:1234"); 165 CPPUNIT_ASSERT(url.IsValid()); 166 CPPUNIT_ASSERT(url.Protocol() == "https"); 167 CPPUNIT_ASSERT(url.HasProtocol()); 168 CPPUNIT_ASSERT(!url.HasUserName()); 169 CPPUNIT_ASSERT(!url.HasPassword()); 170 CPPUNIT_ASSERT(url.Host() == "www.something.co.nz"); 171 CPPUNIT_ASSERT(url.HasHost()); 172 CPPUNIT_ASSERT(url.Port() == 1234); 173 CPPUNIT_ASSERT(url.HasPort()); 174 CPPUNIT_ASSERT(!url.HasPath()); 175 CPPUNIT_ASSERT(!url.HasRequest()); 176 CPPUNIT_ASSERT(!url.HasFragment()); 177 } 178 179 180 void NetworkUrlTest::TestHostWithEmptyPort() 181 { 182 BUrl url("https://www.something.co.nz:"); 183 CPPUNIT_ASSERT(url.IsValid()); 184 CPPUNIT_ASSERT(url.Protocol() == "https"); 185 CPPUNIT_ASSERT(url.HasProtocol()); 186 CPPUNIT_ASSERT(!url.HasUserName()); 187 CPPUNIT_ASSERT(!url.HasPassword()); 188 CPPUNIT_ASSERT(url.Host() == "www.something.co.nz"); 189 CPPUNIT_ASSERT(url.HasHost()); 190 CPPUNIT_ASSERT(!url.HasPort()); 191 CPPUNIT_ASSERT(!url.HasPath()); 192 CPPUNIT_ASSERT(!url.HasRequest()); 193 CPPUNIT_ASSERT(!url.HasFragment()); 194 } 195 196 197 // Invalid Forms --------------------------------------------------------------- 198 199 200 void NetworkUrlTest::TestWhitespaceBefore() 201 { 202 BUrl url(" https://www.something.co.nz/z"); 203 CPPUNIT_ASSERT(!url.IsValid()); 204 } 205 206 207 void NetworkUrlTest::TestWhitespaceAfter() 208 { 209 BUrl url("https://www.something.co.nz/z\t\t "); 210 CPPUNIT_ASSERT(!url.IsValid()); 211 } 212 213 214 void NetworkUrlTest::TestWhitespaceMiddle() 215 { 216 BUrl url("https://www. something.co.nz/z"); 217 CPPUNIT_ASSERT(!url.IsValid()); 218 } 219 220 221 void NetworkUrlTest::TestHttpNoHost() 222 { 223 BUrl url("https:///z"); 224 CPPUNIT_ASSERT(!url.IsValid()); 225 } 226 227 228 // Control --------------------------------------------------------------------- 229 230 231 /*static*/ void 232 NetworkUrlTest::AddTests(BTestSuite& parent) 233 { 234 CppUnit::TestSuite& suite = *new CppUnit::TestSuite("NetworkUrlTest"); 235 236 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 237 "NetworkUrlTest::TestHostAndPortWithNoUserNameAndPassword", 238 &NetworkUrlTest::TestHostAndPortWithNoUserNameAndPassword)); 239 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 240 "NetworkUrlTest::TestWithUserNameAndPasswordNoHostAndPort", 241 &NetworkUrlTest::TestWithUserNameAndPasswordNoHostAndPort)); 242 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 243 "NetworkUrlTest::TestHostWithNoPortOrUserNameAndPassword", 244 &NetworkUrlTest::TestHostWithNoPortOrUserNameAndPassword)); 245 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 246 "NetworkUrlTest::TestHostWithNoPortNoPath", 247 &NetworkUrlTest::TestHostWithNoPortNoPath)); 248 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 249 "NetworkUrlTest::TestHostWithPortNoPath", 250 &NetworkUrlTest::TestHostWithPortNoPath)); 251 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 252 "NetworkUrlTest::TestHostWithEmptyPort", 253 &NetworkUrlTest::TestHostWithEmptyPort)); 254 255 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 256 "NetworkUrlTest::TestWhitespaceBefore", 257 &NetworkUrlTest::TestWhitespaceBefore)); 258 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 259 "NetworkUrlTest::TestWhitespaceAfter", 260 &NetworkUrlTest::TestWhitespaceAfter)); 261 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 262 "NetworkUrlTest::TestWhitespaceMiddle", 263 &NetworkUrlTest::TestWhitespaceMiddle)); 264 265 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 266 "NetworkUrlTest::TestFileUrl", 267 &NetworkUrlTest::TestFileUrl)); 268 suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>( 269 "NetworkUrlTest::TestValidFullUrl", &NetworkUrlTest::TestValidFullUrl)); 270 271 parent.addTest("NetworkUrlTest", &suite); 272 } -
new file src/tests/kits/net/libnetapi/NetworkUrlTest.h
diff --git a/src/tests/kits/net/libnetapi/NetworkUrlTest.h b/src/tests/kits/net/libnetapi/NetworkUrlTest.h new file mode 100644 index 0000000..6b8b7e4
- + 1 /* 2 * Copyright 2016, Andrew Lindesay, apl@lindesay.co.nz 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef NETWORK_URL_TEST_H 6 #define NETWORK_URL_TEST_H 7 8 9 #include <TestCase.h> 10 #include <TestSuite.h> 11 12 13 class NetworkUrlTest : public CppUnit::TestCase { 14 public: 15 NetworkUrlTest(); 16 virtual ~NetworkUrlTest(); 17 18 virtual void setUp(); 19 virtual void tearDown(); 20 21 void TestValidFullUrl(); 22 23 void TestFileUrl(); 24 25 void TestWithUserNameAndPasswordNoHostAndPort(); 26 void TestHostAndPortWithNoUserNameAndPassword(); 27 void TestHostWithNoPortOrUserNameAndPassword(); 28 void TestHostWithNoPortNoPath(); 29 void TestHostWithPortNoPath(); 30 void TestHostWithEmptyPort(); 31 32 void TestWhitespaceBefore(); 33 void TestWhitespaceAfter(); 34 void TestWhitespaceMiddle(); 35 void TestHttpNoHost(); 36 37 static void AddTests(BTestSuite& suite); 38 39 }; 40 41 42 #endif // NETWORK_URL_TEST_H