Ticket #12710: BPackageInfo-urlvalidation-2.diff

File BPackageInfo-urlvalidation-2.diff, 5.0 KB (added by apl-haiku, 8 years ago)
  • src/kits/package/PackageInfoParser.cpp

    diff --git a/src/kits/package/PackageInfoParser.cpp b/src/kits/package/PackageInfoParser.cpp
    index f684815..ed241e7 100644
    a b  
    11/*
    22 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
     3 * Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>
    34 * Distributed under the terms of the MIT License.
    45 */
    56
    BPackageInfo::Parser::_ParseList(ListElementParser& elementParser,  
    508509
    509510void
    510511BPackageInfo::Parser::_ParseStringList(BStringList* value,
    511     bool requireResolvableName, bool convertToLowerCase)
     512    bool requireResolvableName, bool convertToLowerCase,
     513    StringValidator* stringValidator)
    512514{
    513515    struct StringParser : public ListElementParser {
    514516        BStringList* value;
    515517        bool requireResolvableName;
    516518        bool convertToLowerCase;
     519        StringValidator* stringValidator;
    517520
    518521        StringParser(BStringList* value, bool requireResolvableName,
    519             bool convertToLowerCase)
     522            bool convertToLowerCase, StringValidator* stringValidator)
    520523            :
    521524            value(value),
    522525            requireResolvableName(requireResolvableName),
    523             convertToLowerCase(convertToLowerCase)
     526            convertToLowerCase(convertToLowerCase),
     527            stringValidator(stringValidator)
    524528        {
    525529        }
    526530
    BPackageInfo::Parser::_ParseStringList(BStringList* value,  
    541545            if (convertToLowerCase)
    542546                element.ToLower();
    543547
     548            if (stringValidator != NULL)
     549                stringValidator->Validate(element, token.pos);
     550           
    544551            value->Add(element);
    545552        }
    546     } stringParser(value, requireResolvableName, convertToLowerCase);
     553    } stringParser(value, requireResolvableName, convertToLowerCase,
     554        stringValidator);
    547555
    548556    _ParseList(stringParser, true);
    549557}
    BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)  
    10081016                break;
    10091017
    10101018            case B_PACKAGE_INFO_URLS:
    1011                 _ParseStringList(&packageInfo->fURLList);
     1019                UrlStringValidator stringValidator;
     1020                _ParseStringList(&packageInfo->fURLList,
     1021                    false, false, &stringValidator);
    10121022                break;
    10131023
    10141024            case B_PACKAGE_INFO_SOURCE_URLS:
    1015                 _ParseStringList(&packageInfo->fSourceURLList);
     1025                UrlStringValidator stringValidator;
     1026                _ParseStringList(&packageInfo->fSourceURLList,
     1027                    false, false, &stringValidator);
    10161028                break;
    10171029
    10181030            case B_PACKAGE_INFO_GLOBAL_WRITABLE_FILES:
    BPackageInfo::Parser::_IsValidResolvableName(const char* string,  
    11461158}
    11471159
    11481160
     1161/*static*/ bool
     1162BPackageInfo::Parser::UrlStringValidator::_HasUrlProtocol(const BString& url)
     1163{
     1164    return url.StartsWith("http://")
     1165        || url.StartsWith("https://")
     1166        || url.StartsWith("ftp://")
     1167        || url.StartsWith("file:/");
     1168}
     1169
     1170
     1171/*static*/ bool
     1172BPackageInfo::Parser::UrlStringValidator::_IsUrlChar(char ch)
     1173{
     1174    if ( (ch >= 'A' && ch <= 'Z') ||
     1175         (ch >= 'a' && ch <= 'z') ||
     1176         (ch >= '0' && ch <= '9') ) {
     1177        return true;
     1178    }
     1179   
     1180    switch (ch) {
     1181        case '-':
     1182        case '.':
     1183        case '_':
     1184        case '~':
     1185        case ':':
     1186        case '/':
     1187        case '?':
     1188        case '#':
     1189        case '[':
     1190        case ']':
     1191        case '@':
     1192        case '!':
     1193        case '$':
     1194        case '&':
     1195        case '\'':
     1196        case '(':
     1197        case ')':
     1198        case '*':
     1199        case '+':
     1200        case ',':
     1201        case ';':
     1202        case '=':
     1203            return true;
     1204    }
     1205   
     1206    return false;
     1207}
     1208
     1209
     1210void
     1211BPackageInfo::Parser::UrlStringValidator::Validate(const BString& url, const char *pos)
     1212{
     1213    for (int32 i = 0; i < url.Length(); i++) {
     1214        if (!_IsUrlChar(url.ByteAt(i)))
     1215            throw ParseError("invalid character in url", pos);
     1216    }
     1217   
     1218    if (!_HasUrlProtocol(url))
     1219        throw ParseError("missing or unrecognized protocol in url", pos);
     1220}
     1221
     1222
    11491223} // namespace BPackageKit
  • src/kits/package/PackageInfoParser.h

    diff --git a/src/kits/package/PackageInfoParser.h b/src/kits/package/PackageInfoParser.h
    index 6824b9e..3cdf82e 100644
    a b  
    11/*
    22 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
     3 * Copyright 2016, Andrew Lindesay <apl@lindesay.co.nz>
    34 * Distributed under the terms of the MIT License.
    45 */
    56#ifndef PACKAGE_INFO_PARSER_H
    public:  
    3132                                    BPackageResolvableExpression& _expression);
    3233
    3334private:
     35            struct UrlStringValidator;
     36            struct StringValidator;
    3437            struct ParseError;
    3538            struct Token;
    3639            struct ListElementParser;
    private:  
    7477                                    bool allowSingleNonListElement);
    7578            void                _ParseStringList(BStringList* value,
    7679                                    bool requireResolvableName = false,
    77                                     bool convertToLowerCase = false);
     80                                    bool convertToLowerCase = false,
     81                                    StringValidator* stringValidator = NULL);
    7882            void                _ParseResolvableList(
    7983                                    BObjectList<BPackageResolvable>* value);
    8084            void                _ParseResolvableExprList(
    struct BPackageInfo::Parser::ListElementParser {  
    152156};
    153157
    154158
     159struct BPackageInfo::Parser::StringValidator {
     160public:
     161    virtual void Validate(const BString &string, const char *pos) = 0;
     162};
     163
     164
     165struct BPackageInfo::Parser::UrlStringValidator : public BPackageInfo::Parser::StringValidator {
     166private:
     167    static  bool                _HasUrlProtocol(const BString& url);
     168    static  bool                _IsUrlChar(char ch);
     169
     170public:
     171    virtual void                Validate(const BString &string, const char *pos);
     172};
     173
     174
    155175} // namespace BPackageKit
    156176
    157177