BPackageInfo::Parser: Validate URL strings.
Fixes #12710. Signed-off-by: Augustin Cavalier <waddlesplash@gmail.com> I fixed the modifications to the Jamfiles in src/bin, they were all wrong in the patch.
This commit is contained in:
parent
a4f86e7f78
commit
fa2dd9c45f
@ -496,8 +496,8 @@ if $(HOST_PLATFORM_BEOS_COMPATIBLE) {
|
||||
HOST_LIBROOT += /usr/lib/libgnuregex.so ;
|
||||
HOST_STATIC_LIBROOT += /usr/lib/libgnuregex.so ;
|
||||
} else if $(HOST_PLATFORM) = darwin {
|
||||
HOST_LIBROOT += libgnuregex_build.a ;
|
||||
HOST_STATIC_LIBROOT += libgnuregex_build.a ;
|
||||
HOST_LIBROOT += libgnuregex_build.so ;
|
||||
HOST_STATIC_LIBROOT += libgnuregex_build.so ;
|
||||
}
|
||||
|
||||
# The BeOS compilers define __INTEL__ respectively __POWERPC__. On the
|
||||
|
12
docs/develop/build/libgnuregex.md
Normal file
12
docs/develop/build/libgnuregex.md
Normal file
@ -0,0 +1,12 @@
|
||||
# libgnuregex
|
||||
|
||||
This library exists because some systems don't have a flavor of regex library
|
||||
built-in which supports groups. This variant does include group-support. An
|
||||
example of where this comes into play is with the `BUrl` class where URLs are
|
||||
parsed, in part, using regular expressions.
|
||||
|
||||
## Use with MacOS-X
|
||||
|
||||
In the case of MacOS-X, the dynamic-library build product
|
||||
`libgnuregex_build.so` can be configured for use by configuring the
|
||||
`DYLD_INSERT_LIBRARIES` environment variable.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Copyright 2010-2016 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_H_
|
||||
@ -33,7 +33,7 @@ public:
|
||||
BUrl& SetPath(const BString& path);
|
||||
BUrl& SetRequest(const BString& request);
|
||||
BUrl& SetFragment(const BString& fragment);
|
||||
|
||||
|
||||
// URL fields access
|
||||
const BString& UrlString() const;
|
||||
const BString& Protocol() const;
|
||||
@ -46,7 +46,7 @@ public:
|
||||
const BString& Path() const;
|
||||
const BString& Request() const;
|
||||
const BString& Fragment() const;
|
||||
|
||||
|
||||
// URL fields tests
|
||||
bool IsValid() const;
|
||||
bool HasProtocol() const;
|
||||
@ -64,21 +64,25 @@ public:
|
||||
void UrlEncode(bool strict = false);
|
||||
void UrlDecode(bool strict = false);
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
status_t IDNAToAscii();
|
||||
status_t IDNAToUnicode();
|
||||
#endif
|
||||
|
||||
// Url encoding/decoding of strings
|
||||
static BString UrlEncode(const BString& url,
|
||||
bool strict = false,
|
||||
static BString UrlEncode(const BString& url,
|
||||
bool strict = false,
|
||||
bool directory = false);
|
||||
static BString UrlDecode(const BString& url,
|
||||
static BString UrlDecode(const BString& url,
|
||||
bool strict = false);
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
// utility functionality
|
||||
bool HasPreferredApplication() const;
|
||||
BString PreferredApplication() const;
|
||||
status_t OpenWithPreferredApplication(
|
||||
bool onProblemAskUser = true) const;
|
||||
#endif
|
||||
|
||||
// BArchivable members
|
||||
virtual status_t Archive(BMessage* into,
|
||||
@ -93,19 +97,20 @@ public:
|
||||
const BUrl& operator=(const BUrl& other);
|
||||
const BUrl& operator=(const BString& string);
|
||||
const BUrl& operator=(const char* string);
|
||||
|
||||
|
||||
// URL to string conversion
|
||||
operator const char*() const;
|
||||
|
||||
private:
|
||||
void _ResetFields();
|
||||
bool _ContainsDelimiter(const BString& url);
|
||||
void _ExplodeUrlString(const BString& urlString);
|
||||
BString _MergePath(const BString& relative) const;
|
||||
void _SetPathUnsafe(const BString& path);
|
||||
|
||||
static BString _DoUrlEncodeChunk(const BString& chunk,
|
||||
static BString _DoUrlEncodeChunk(const BString& chunk,
|
||||
bool strict, bool directory = false);
|
||||
static BString _DoUrlDecodeChunk(const BString& chunk,
|
||||
static BString _DoUrlDecodeChunk(const BString& chunk,
|
||||
bool strict);
|
||||
|
||||
bool _IsProtocolValid();
|
||||
@ -128,7 +133,7 @@ private:
|
||||
BString fPath;
|
||||
BString fRequest;
|
||||
BString fFragment;
|
||||
|
||||
|
||||
mutable bool fUrlStringValid : 1;
|
||||
mutable bool fAuthorityValid : 1;
|
||||
mutable bool fUserInfoValid : 1;
|
||||
|
@ -134,7 +134,7 @@ StdBinCommands
|
||||
ramdisk.cpp
|
||||
: shared be [ TargetLibsupc++ ] : $(haiku-utils_rsrc) ;
|
||||
|
||||
# standard commands that need libbe.so, libbnetapi.solibsupc++.so
|
||||
# standard commands that need libbe.so, libbnetapi.so, libsupc++.so
|
||||
StdBinCommands
|
||||
open.cpp
|
||||
urlwrapper.cpp
|
||||
|
@ -15,6 +15,6 @@ BinCommand package :
|
||||
PackageWriterListener.cpp
|
||||
PackageWritingUtils.cpp
|
||||
:
|
||||
package be
|
||||
package be bnetapi
|
||||
[ TargetLibsupc++ ]
|
||||
;
|
||||
|
@ -11,14 +11,18 @@ BuildPlatformSharedLibrary libbe_build.so :
|
||||
<libbe_build>app_kit.o
|
||||
<libbe_build>icon_kit.o
|
||||
<libbe_build>interface_kit.o
|
||||
<libbe_build>network_kit.o
|
||||
<libbe_build>storage_kit.o
|
||||
<libbe_build>support_kit.o
|
||||
|
||||
libshared_build.a
|
||||
|
||||
z $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
|
||||
;
|
||||
|
||||
SubInclude HAIKU_TOP src build libbe app ;
|
||||
SubInclude HAIKU_TOP src build libbe icon ;
|
||||
SubInclude HAIKU_TOP src build libbe interface ;
|
||||
SubInclude HAIKU_TOP src build libbe network ;
|
||||
SubInclude HAIKU_TOP src build libbe storage ;
|
||||
SubInclude HAIKU_TOP src build libbe support ;
|
||||
|
15
src/build/libbe/network/Jamfile
Normal file
15
src/build/libbe/network/Jamfile
Normal file
@ -0,0 +1,15 @@
|
||||
SubDir HAIKU_TOP src build libbe network;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers os net ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers private shared ] : true ;
|
||||
|
||||
UsePrivateBuildHeaders app interface shared network ;
|
||||
|
||||
USES_BE_API on <libbe_build>network_kit.o = true ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits network libnetapi ] ;
|
||||
|
||||
BuildPlatformMergeObjectPIC <libbe_build>network_kit.o :
|
||||
Url.cpp
|
||||
;
|
@ -1,3 +1,7 @@
|
||||
SubDir HAIKU_TOP src build libgnuregex ;
|
||||
|
||||
BuildPlatformStaticLibrary libgnuregex_build.a : regex.c ;
|
||||
BuildPlatformSharedLibrary libgnuregex_build.so :
|
||||
regex.c
|
||||
:
|
||||
# no linked libraries here
|
||||
;
|
||||
|
@ -2,6 +2,8 @@ SubDir HAIKU_TOP src build libpackage ;
|
||||
|
||||
UsePrivateBuildHeaders kernel package shared storage support ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers os net ] : true ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg v1 ] ;
|
||||
|
@ -2,6 +2,8 @@ SubDir HAIKU_TOP src build libshared ;
|
||||
|
||||
USES_BE_API on libshared_build.a = true ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers private shared ] : true ;
|
||||
|
||||
UsePrivateBuildHeaders shared ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits shared ] ;
|
||||
@ -10,4 +12,9 @@ BuildPlatformStaticLibraryPIC libshared_build.a :
|
||||
Keymap.cpp
|
||||
NaturalCompare.cpp
|
||||
SHA256.cpp
|
||||
RegExp.cpp
|
||||
|
||||
:
|
||||
|
||||
# no shared libs, but will require 'libgnuregex' dynamic library on Darwin
|
||||
;
|
||||
|
@ -1,9 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Copyright 2010-2016 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Christophe Huriaux, c.huriaux@gmail.com
|
||||
* Andrew Lindesay, apl@lindesay.co.nz
|
||||
*/
|
||||
|
||||
|
||||
@ -17,11 +18,15 @@
|
||||
#include <MimeType.h>
|
||||
#include <Roster.h>
|
||||
|
||||
#include <ICUWrapper.h>
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
#include <ICUWrapper.h>
|
||||
#endif
|
||||
#include <RegExp.h>
|
||||
|
||||
#include <unicode/idna.h>
|
||||
#include <unicode/stringpiece.h>
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
#include <unicode/idna.h>
|
||||
#include <unicode/stringpiece.h>
|
||||
#endif
|
||||
|
||||
|
||||
static const char* kArchivedUrl = "be:url string";
|
||||
@ -498,8 +503,14 @@ BUrl::Fragment() const
|
||||
bool
|
||||
BUrl::IsValid() const
|
||||
{
|
||||
if (!fHasProtocol)
|
||||
return false;
|
||||
|
||||
if (fProtocol == "http" || fProtocol == "https" || fProtocol == "ftp")
|
||||
return fHasHost;
|
||||
|
||||
// TODO: Implement for real!
|
||||
return fHasProtocol && (fHasHost || fHasPath);
|
||||
return fHasHost || fHasPath;
|
||||
}
|
||||
|
||||
|
||||
@ -598,6 +609,7 @@ BUrl::UrlDecode(bool strict)
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
status_t
|
||||
BUrl::IDNAToAscii()
|
||||
{
|
||||
@ -618,8 +630,10 @@ BUrl::IDNAToAscii()
|
||||
fHost = result;
|
||||
return B_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
status_t
|
||||
BUrl::IDNAToUnicode()
|
||||
{
|
||||
@ -640,11 +654,13 @@ BUrl::IDNAToUnicode()
|
||||
fHost = result;
|
||||
return B_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// #pragma mark - utility functionality
|
||||
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
bool
|
||||
BUrl::HasPreferredApplication() const
|
||||
{
|
||||
@ -657,8 +673,10 @@ BUrl::HasPreferredApplication() const
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
BString
|
||||
BUrl::PreferredApplication() const
|
||||
{
|
||||
@ -669,8 +687,10 @@ BUrl::PreferredApplication() const
|
||||
|
||||
return BString(appSignature);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
status_t
|
||||
BUrl::OpenWithPreferredApplication(bool onProblemAskUser) const
|
||||
{
|
||||
@ -710,6 +730,7 @@ BUrl::OpenWithPreferredApplication(bool onProblemAskUser) const
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// #pragma mark Url encoding/decoding of string
|
||||
@ -866,6 +887,28 @@ BUrl::_ResetFields()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BUrl::_ContainsDelimiter(const BString& url)
|
||||
{
|
||||
int32 len = url.Length();
|
||||
|
||||
for (int32 i = 0; i < len; i++) {
|
||||
switch (url[i]) {
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '<':
|
||||
case '>':
|
||||
case '"':
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BUrl::_ExplodeUrlString(const BString& url)
|
||||
{
|
||||
@ -875,6 +918,11 @@ BUrl::_ExplodeUrlString(const BString& url)
|
||||
|
||||
_ResetFields();
|
||||
|
||||
// RFC3986, Appendix C; the URL should not contain whitespace or delimiters
|
||||
// by this point.
|
||||
if (_ContainsDelimiter(url))
|
||||
return; // TODO error handing
|
||||
|
||||
RegExp::MatchResult match = urlMatcher.Match(url.String());
|
||||
|
||||
if (!match.HasMatched())
|
||||
@ -883,6 +931,7 @@ BUrl::_ExplodeUrlString(const BString& url)
|
||||
// Scheme/Protocol
|
||||
url.CopyInto(fProtocol, match.GroupStartOffsetAt(1),
|
||||
match.GroupEndOffsetAt(1) - match.GroupStartOffsetAt(1));
|
||||
|
||||
if (!_IsProtocolValid()) {
|
||||
fHasProtocol = false;
|
||||
fProtocol.Truncate(0);
|
||||
@ -981,6 +1030,7 @@ BUrl::SetAuthority(const BString& authority)
|
||||
return;
|
||||
|
||||
int32 userInfoEnd = fAuthority.FindFirst('@');
|
||||
int16 hostAndPortStart = 0;
|
||||
|
||||
// URL contains userinfo field
|
||||
if (userInfoEnd != -1) {
|
||||
@ -1000,39 +1050,23 @@ BUrl::SetAuthority(const BString& authority)
|
||||
} else {
|
||||
SetUserName(fUser);
|
||||
}
|
||||
|
||||
hostAndPortStart = userInfoEnd + 1;
|
||||
}
|
||||
|
||||
int16 hostEnd = fAuthority.FindFirst(':', hostAndPortStart);
|
||||
|
||||
// Extract the host part
|
||||
int16 hostEnd = fAuthority.FindFirst(':', userInfoEnd);
|
||||
userInfoEnd++;
|
||||
|
||||
if (hostEnd < 0) {
|
||||
// no ':' found, the host extends to the end of the URL
|
||||
hostEnd = fAuthority.Length() + 1;
|
||||
if (hostEnd != B_ERROR) {
|
||||
if (hostEnd < fAuthority.Length()-1) {
|
||||
fPort = atoi(&(fAuthority.String())[hostEnd+1]);
|
||||
fHasPort = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
hostEnd = fAuthority.Length();
|
||||
|
||||
// The host is likely to be present if an authority is
|
||||
// defined, but in some weird cases, it's not.
|
||||
if (hostEnd != userInfoEnd) {
|
||||
fAuthority.CopyInto(fHost, userInfoEnd, hostEnd - userInfoEnd);
|
||||
SetHost(fHost);
|
||||
}
|
||||
|
||||
// Extract the port part
|
||||
fPort = 0;
|
||||
if (fAuthority.ByteAt(hostEnd) == ':') {
|
||||
hostEnd++;
|
||||
int16 portEnd = fAuthority.Length();
|
||||
|
||||
BString portString;
|
||||
fAuthority.CopyInto(portString, hostEnd, portEnd - hostEnd);
|
||||
fPort = atoi(portString.String());
|
||||
|
||||
// Even if the port is invalid, the URL is considered to
|
||||
// have a port.
|
||||
fHasPort = portString.Length() > 0;
|
||||
}
|
||||
fAuthority.CopyInto(fHost, hostAndPortStart, hostEnd - hostAndPortStart);
|
||||
SetHost(fHost);
|
||||
}
|
||||
|
||||
|
||||
@ -1088,7 +1122,7 @@ BUrl::_DoUrlDecodeChunk(const BString& chunk, bool strict)
|
||||
result << decoded;
|
||||
} else
|
||||
result << chunk[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -129,9 +129,11 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
SolverResult.cpp
|
||||
:
|
||||
shared
|
||||
bnetapi
|
||||
be
|
||||
[ BuildFeatureAttribute curl : library ]
|
||||
[ TargetLibstdc++ ]
|
||||
$(TARGET_NETWORK_LIBS)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -13,6 +14,7 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <Url.h>
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
@ -508,19 +510,22 @@ BPackageInfo::Parser::_ParseList(ListElementParser& elementParser,
|
||||
|
||||
void
|
||||
BPackageInfo::Parser::_ParseStringList(BStringList* value,
|
||||
bool requireResolvableName, bool convertToLowerCase)
|
||||
bool requireResolvableName, bool convertToLowerCase,
|
||||
StringValidator* stringValidator)
|
||||
{
|
||||
struct StringParser : public ListElementParser {
|
||||
BStringList* value;
|
||||
bool requireResolvableName;
|
||||
bool convertToLowerCase;
|
||||
StringValidator* stringValidator;
|
||||
|
||||
StringParser(BStringList* value, bool requireResolvableName,
|
||||
bool convertToLowerCase)
|
||||
bool convertToLowerCase, StringValidator* stringValidator)
|
||||
:
|
||||
value(value),
|
||||
requireResolvableName(requireResolvableName),
|
||||
convertToLowerCase(convertToLowerCase)
|
||||
convertToLowerCase(convertToLowerCase),
|
||||
stringValidator(stringValidator)
|
||||
{
|
||||
}
|
||||
|
||||
@ -541,9 +546,13 @@ BPackageInfo::Parser::_ParseStringList(BStringList* value,
|
||||
if (convertToLowerCase)
|
||||
element.ToLower();
|
||||
|
||||
if (stringValidator != NULL)
|
||||
stringValidator->Validate(element, token.pos);
|
||||
|
||||
value->Add(element);
|
||||
}
|
||||
} stringParser(value, requireResolvableName, convertToLowerCase);
|
||||
} stringParser(value, requireResolvableName, convertToLowerCase,
|
||||
stringValidator);
|
||||
|
||||
_ParseList(stringParser, true);
|
||||
}
|
||||
@ -1008,11 +1017,19 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_URLS:
|
||||
_ParseStringList(&packageInfo->fURLList);
|
||||
{
|
||||
UrlStringValidator stringValidator;
|
||||
_ParseStringList(&packageInfo->fURLList,
|
||||
false, false, &stringValidator);
|
||||
}
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SOURCE_URLS:
|
||||
_ParseStringList(&packageInfo->fSourceURLList);
|
||||
{
|
||||
UrlStringValidator stringValidator;
|
||||
_ParseStringList(&packageInfo->fSourceURLList,
|
||||
false, false, &stringValidator);
|
||||
}
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_GLOBAL_WRITABLE_FILES:
|
||||
@ -1145,5 +1162,15 @@ BPackageInfo::Parser::_IsValidResolvableName(const char* string,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BPackageInfo::Parser::UrlStringValidator::Validate(const BString& urlString,
|
||||
const char* pos)
|
||||
{
|
||||
BUrl url(urlString);
|
||||
|
||||
if (!url.IsValid())
|
||||
throw ParseError("invalid url", pos);
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_INFO_PARSER_H
|
||||
@ -31,6 +32,8 @@ public:
|
||||
BPackageResolvableExpression& _expression);
|
||||
|
||||
private:
|
||||
struct UrlStringValidator;
|
||||
struct StringValidator;
|
||||
struct ParseError;
|
||||
struct Token;
|
||||
struct ListElementParser;
|
||||
@ -74,7 +77,8 @@ private:
|
||||
bool allowSingleNonListElement);
|
||||
void _ParseStringList(BStringList* value,
|
||||
bool requireResolvableName = false,
|
||||
bool convertToLowerCase = false);
|
||||
bool convertToLowerCase = false,
|
||||
StringValidator* stringValidator = NULL);
|
||||
void _ParseResolvableList(
|
||||
BObjectList<BPackageResolvable>* value);
|
||||
void _ParseResolvableExprList(
|
||||
@ -152,6 +156,19 @@ struct BPackageInfo::Parser::ListElementParser {
|
||||
};
|
||||
|
||||
|
||||
struct BPackageInfo::Parser::StringValidator {
|
||||
public:
|
||||
virtual void Validate(const BString &string, const char *pos) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct BPackageInfo::Parser::UrlStringValidator
|
||||
: public BPackageInfo::Parser::StringValidator {
|
||||
public:
|
||||
virtual void Validate(const BString &string, const char* pos);
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
||||
|
||||
|
@ -5,6 +5,7 @@ UnitTestLib libnetapitest.so :
|
||||
|
||||
NetworkAddressTest.cpp
|
||||
NetworkInterfaceTest.cpp
|
||||
NetworkUrlTest.cpp
|
||||
|
||||
: be bnetapi network [ TargetLibstdc++ ] [ TargetLibsupc++ ]
|
||||
;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "NetworkAddressTest.h"
|
||||
#include "NetworkInterfaceTest.h"
|
||||
#include "NetworkUrlTest.h"
|
||||
|
||||
|
||||
BTestSuite*
|
||||
@ -18,6 +19,7 @@ getTestSuite()
|
||||
|
||||
NetworkAddressTest::AddTests(*suite);
|
||||
NetworkInterfaceTest::AddTests(*suite);
|
||||
NetworkUrlTest::AddTests(*suite);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
272
src/tests/kits/net/libnetapi/NetworkUrlTest.cpp
Normal file
272
src/tests/kits/net/libnetapi/NetworkUrlTest.cpp
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright 2016, Andrew Lindesay, apl@lindesay.co.nz.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "NetworkUrlTest.h"
|
||||
|
||||
#include <Url.h>
|
||||
|
||||
#include <cppunit/TestCaller.h>
|
||||
#include <cppunit/TestSuite.h>
|
||||
|
||||
|
||||
NetworkUrlTest::NetworkUrlTest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NetworkUrlTest::~NetworkUrlTest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NetworkUrlTest::setUp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NetworkUrlTest::tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// General Tests ---------------------------------------------------------------
|
||||
|
||||
/*
|
||||
This is the "happy days" tests that checks that a URL featuring all of the
|
||||
parsed elements successfully processes and the elements are present.
|
||||
*/
|
||||
|
||||
void NetworkUrlTest::TestValidFullUrl()
|
||||
{
|
||||
BUrl url("http://ewe:pea@www.something.co.nz:8888/some/path?key1=value1#fragment");
|
||||
CPPUNIT_ASSERT(url.IsValid());
|
||||
CPPUNIT_ASSERT(url.Protocol() == "http");
|
||||
CPPUNIT_ASSERT(url.HasProtocol());
|
||||
CPPUNIT_ASSERT(url.UserName() == "ewe");
|
||||
CPPUNIT_ASSERT(url.HasUserName());
|
||||
CPPUNIT_ASSERT(url.Password() == "pea");
|
||||
CPPUNIT_ASSERT(url.HasPassword());
|
||||
CPPUNIT_ASSERT(url.Host() == "www.something.co.nz");
|
||||
CPPUNIT_ASSERT(url.HasHost());
|
||||
CPPUNIT_ASSERT(url.Port() == 8888);
|
||||
CPPUNIT_ASSERT(url.HasPort());
|
||||
CPPUNIT_ASSERT(url.Path() == "/some/path");
|
||||
CPPUNIT_ASSERT(url.HasPath());
|
||||
CPPUNIT_ASSERT(url.Request() == "key1=value1");
|
||||
CPPUNIT_ASSERT(url.HasRequest());
|
||||
CPPUNIT_ASSERT(url.Fragment() == "fragment");
|
||||
CPPUNIT_ASSERT(url.HasFragment());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestFileUrl()
|
||||
{
|
||||
BUrl url("file:///northisland/wellington/brooklyn/windturbine");
|
||||
CPPUNIT_ASSERT(url.IsValid());
|
||||
CPPUNIT_ASSERT(url.Protocol() == "file");
|
||||
CPPUNIT_ASSERT(url.HasProtocol());
|
||||
CPPUNIT_ASSERT(!url.HasUserName());
|
||||
CPPUNIT_ASSERT(!url.HasPassword());
|
||||
CPPUNIT_ASSERT(url.Host() == "");
|
||||
CPPUNIT_ASSERT(url.HasHost());
|
||||
CPPUNIT_ASSERT(!url.HasPort());
|
||||
CPPUNIT_ASSERT(url.Path() == "/northisland/wellington/brooklyn/windturbine");
|
||||
CPPUNIT_ASSERT(url.HasPath());
|
||||
CPPUNIT_ASSERT(!url.HasRequest());
|
||||
CPPUNIT_ASSERT(!url.HasFragment());
|
||||
}
|
||||
|
||||
|
||||
// Authority Tests (UserName, Password, Host, Port) ----------------------------
|
||||
|
||||
|
||||
void NetworkUrlTest::TestWithUserNameAndPasswordNoHostAndPort()
|
||||
{
|
||||
BUrl url("wierd://tea:tree@/x");
|
||||
CPPUNIT_ASSERT(url.IsValid());
|
||||
CPPUNIT_ASSERT(url.Protocol() == "wierd");
|
||||
CPPUNIT_ASSERT(url.HasProtocol());
|
||||
CPPUNIT_ASSERT(url.UserName() == "tea");
|
||||
CPPUNIT_ASSERT(url.HasUserName());
|
||||
CPPUNIT_ASSERT(url.Password() == "tree");
|
||||
CPPUNIT_ASSERT(url.HasPassword());
|
||||
CPPUNIT_ASSERT(url.Host() == "");
|
||||
CPPUNIT_ASSERT(!url.HasHost());
|
||||
CPPUNIT_ASSERT(!url.HasPort());
|
||||
CPPUNIT_ASSERT(url.Path() == "/x");
|
||||
CPPUNIT_ASSERT(url.HasPath());
|
||||
CPPUNIT_ASSERT(!url.HasRequest());
|
||||
CPPUNIT_ASSERT(!url.HasFragment());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestHostAndPortWithNoUserNameAndPassword()
|
||||
{
|
||||
BUrl url("https://www.something.co.nz:443/z");
|
||||
CPPUNIT_ASSERT(url.IsValid());
|
||||
CPPUNIT_ASSERT(url.Protocol() == "https");
|
||||
CPPUNIT_ASSERT(url.HasProtocol());
|
||||
CPPUNIT_ASSERT(!url.HasUserName());
|
||||
CPPUNIT_ASSERT(!url.HasPassword());
|
||||
CPPUNIT_ASSERT(url.Port() == 443);
|
||||
CPPUNIT_ASSERT(url.HasPort());
|
||||
CPPUNIT_ASSERT(url.Host() == "www.something.co.nz");
|
||||
CPPUNIT_ASSERT(url.HasHost());
|
||||
CPPUNIT_ASSERT(url.Path() == "/z");
|
||||
CPPUNIT_ASSERT(url.HasPath());
|
||||
CPPUNIT_ASSERT(!url.HasRequest());
|
||||
CPPUNIT_ASSERT(!url.HasFragment());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestHostWithNoPortOrUserNameAndPassword()
|
||||
{
|
||||
BUrl url("https://www.something.co.nz/z");
|
||||
CPPUNIT_ASSERT(url.IsValid());
|
||||
CPPUNIT_ASSERT(url.Protocol() == "https");
|
||||
CPPUNIT_ASSERT(url.HasProtocol());
|
||||
CPPUNIT_ASSERT(!url.HasUserName());
|
||||
CPPUNIT_ASSERT(!url.HasPassword());
|
||||
CPPUNIT_ASSERT(url.Host() == "www.something.co.nz");
|
||||
CPPUNIT_ASSERT(url.HasHost());
|
||||
CPPUNIT_ASSERT(!url.HasPort());
|
||||
CPPUNIT_ASSERT(url.Path() == "/z");
|
||||
CPPUNIT_ASSERT(url.HasPath());
|
||||
CPPUNIT_ASSERT(!url.HasRequest());
|
||||
CPPUNIT_ASSERT(!url.HasFragment());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestHostWithNoPortNoPath()
|
||||
{
|
||||
BUrl url("https://www.something.co.nz");
|
||||
CPPUNIT_ASSERT(url.IsValid());
|
||||
CPPUNIT_ASSERT(url.Protocol() == "https");
|
||||
CPPUNIT_ASSERT(url.HasProtocol());
|
||||
CPPUNIT_ASSERT(!url.HasUserName());
|
||||
CPPUNIT_ASSERT(!url.HasPassword());
|
||||
CPPUNIT_ASSERT(url.Host() == "www.something.co.nz");
|
||||
CPPUNIT_ASSERT(url.HasHost());
|
||||
CPPUNIT_ASSERT(!url.HasPort());
|
||||
CPPUNIT_ASSERT(!url.HasPath());
|
||||
CPPUNIT_ASSERT(!url.HasRequest());
|
||||
CPPUNIT_ASSERT(!url.HasFragment());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestHostWithPortNoPath()
|
||||
{
|
||||
BUrl url("https://www.something.co.nz:1234");
|
||||
CPPUNIT_ASSERT(url.IsValid());
|
||||
CPPUNIT_ASSERT(url.Protocol() == "https");
|
||||
CPPUNIT_ASSERT(url.HasProtocol());
|
||||
CPPUNIT_ASSERT(!url.HasUserName());
|
||||
CPPUNIT_ASSERT(!url.HasPassword());
|
||||
CPPUNIT_ASSERT(url.Host() == "www.something.co.nz");
|
||||
CPPUNIT_ASSERT(url.HasHost());
|
||||
CPPUNIT_ASSERT(url.Port() == 1234);
|
||||
CPPUNIT_ASSERT(url.HasPort());
|
||||
CPPUNIT_ASSERT(!url.HasPath());
|
||||
CPPUNIT_ASSERT(!url.HasRequest());
|
||||
CPPUNIT_ASSERT(!url.HasFragment());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestHostWithEmptyPort()
|
||||
{
|
||||
BUrl url("https://www.something.co.nz:");
|
||||
CPPUNIT_ASSERT(url.IsValid());
|
||||
CPPUNIT_ASSERT(url.Protocol() == "https");
|
||||
CPPUNIT_ASSERT(url.HasProtocol());
|
||||
CPPUNIT_ASSERT(!url.HasUserName());
|
||||
CPPUNIT_ASSERT(!url.HasPassword());
|
||||
CPPUNIT_ASSERT(url.Host() == "www.something.co.nz");
|
||||
CPPUNIT_ASSERT(url.HasHost());
|
||||
CPPUNIT_ASSERT(!url.HasPort());
|
||||
CPPUNIT_ASSERT(!url.HasPath());
|
||||
CPPUNIT_ASSERT(!url.HasRequest());
|
||||
CPPUNIT_ASSERT(!url.HasFragment());
|
||||
}
|
||||
|
||||
|
||||
// Invalid Forms ---------------------------------------------------------------
|
||||
|
||||
|
||||
void NetworkUrlTest::TestWhitespaceBefore()
|
||||
{
|
||||
BUrl url(" https://www.something.co.nz/z");
|
||||
CPPUNIT_ASSERT(!url.IsValid());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestWhitespaceAfter()
|
||||
{
|
||||
BUrl url("https://www.something.co.nz/z\t\t ");
|
||||
CPPUNIT_ASSERT(!url.IsValid());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestWhitespaceMiddle()
|
||||
{
|
||||
BUrl url("https://www. something.co.nz/z");
|
||||
CPPUNIT_ASSERT(!url.IsValid());
|
||||
}
|
||||
|
||||
|
||||
void NetworkUrlTest::TestHttpNoHost()
|
||||
{
|
||||
BUrl url("https:///z");
|
||||
CPPUNIT_ASSERT(!url.IsValid());
|
||||
}
|
||||
|
||||
|
||||
// Control ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/*static*/ void
|
||||
NetworkUrlTest::AddTests(BTestSuite& parent)
|
||||
{
|
||||
CppUnit::TestSuite& suite = *new CppUnit::TestSuite("NetworkUrlTest");
|
||||
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestHostAndPortWithNoUserNameAndPassword",
|
||||
&NetworkUrlTest::TestHostAndPortWithNoUserNameAndPassword));
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestWithUserNameAndPasswordNoHostAndPort",
|
||||
&NetworkUrlTest::TestWithUserNameAndPasswordNoHostAndPort));
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestHostWithNoPortOrUserNameAndPassword",
|
||||
&NetworkUrlTest::TestHostWithNoPortOrUserNameAndPassword));
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestHostWithNoPortNoPath",
|
||||
&NetworkUrlTest::TestHostWithNoPortNoPath));
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestHostWithPortNoPath",
|
||||
&NetworkUrlTest::TestHostWithPortNoPath));
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestHostWithEmptyPort",
|
||||
&NetworkUrlTest::TestHostWithEmptyPort));
|
||||
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestWhitespaceBefore",
|
||||
&NetworkUrlTest::TestWhitespaceBefore));
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestWhitespaceAfter",
|
||||
&NetworkUrlTest::TestWhitespaceAfter));
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestWhitespaceMiddle",
|
||||
&NetworkUrlTest::TestWhitespaceMiddle));
|
||||
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestFileUrl",
|
||||
&NetworkUrlTest::TestFileUrl));
|
||||
suite.addTest(new CppUnit::TestCaller<NetworkUrlTest>(
|
||||
"NetworkUrlTest::TestValidFullUrl", &NetworkUrlTest::TestValidFullUrl));
|
||||
|
||||
parent.addTest("NetworkUrlTest", &suite);
|
||||
}
|
42
src/tests/kits/net/libnetapi/NetworkUrlTest.h
Normal file
42
src/tests/kits/net/libnetapi/NetworkUrlTest.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2016, Andrew Lindesay, apl@lindesay.co.nz
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NETWORK_URL_TEST_H
|
||||
#define NETWORK_URL_TEST_H
|
||||
|
||||
|
||||
#include <TestCase.h>
|
||||
#include <TestSuite.h>
|
||||
|
||||
|
||||
class NetworkUrlTest : public CppUnit::TestCase {
|
||||
public:
|
||||
NetworkUrlTest();
|
||||
virtual ~NetworkUrlTest();
|
||||
|
||||
virtual void setUp();
|
||||
virtual void tearDown();
|
||||
|
||||
void TestValidFullUrl();
|
||||
|
||||
void TestFileUrl();
|
||||
|
||||
void TestWithUserNameAndPasswordNoHostAndPort();
|
||||
void TestHostAndPortWithNoUserNameAndPassword();
|
||||
void TestHostWithNoPortOrUserNameAndPassword();
|
||||
void TestHostWithNoPortNoPath();
|
||||
void TestHostWithPortNoPath();
|
||||
void TestHostWithEmptyPort();
|
||||
|
||||
void TestWhitespaceBefore();
|
||||
void TestWhitespaceAfter();
|
||||
void TestWhitespaceMiddle();
|
||||
void TestHttpNoHost();
|
||||
|
||||
static void AddTests(BTestSuite& suite);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // NETWORK_URL_TEST_H
|
Loading…
Reference in New Issue
Block a user