File indexing completed on 2024-05-05 17:42:44

0001 /*
0002     SPDX-FileCopyrightText: 2018 Bruce Anderson <banderson19com@san.rr.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "simpleiplistvalidator.h"
0008 
0009 #include <QStringList>
0010 #include <QVector>
0011 
0012 SimpleIpListValidator::SimpleIpListValidator(AddressStyle style, AddressType type, QObject *parent)
0013     : QValidator(parent)
0014 {
0015     if (type == Ipv4 || type == Both) {
0016         SimpleIpV4AddressValidator::AddressStyle ipv4Style;
0017         if (style == Base)
0018             ipv4Style = SimpleIpV4AddressValidator::AddressStyle::Base;
0019         else if (style == WithCidr)
0020             ipv4Style = SimpleIpV4AddressValidator::AddressStyle::WithCidr;
0021         else
0022             ipv4Style = SimpleIpV4AddressValidator::AddressStyle::WithPort;
0023         m_ipv4Validator = new SimpleIpV4AddressValidator(ipv4Style, this);
0024     }
0025     if (type == Ipv6 || type == Both) {
0026         SimpleIpV6AddressValidator::AddressStyle ipv6Style;
0027         if (style == Base)
0028             ipv6Style = SimpleIpV6AddressValidator::AddressStyle::Base;
0029         else if (style == WithCidr)
0030             ipv6Style = SimpleIpV6AddressValidator::AddressStyle::WithCidr;
0031         else
0032             ipv6Style = SimpleIpV6AddressValidator::AddressStyle::WithPort;
0033         m_ipv6Validator = new SimpleIpV6AddressValidator(ipv6Style, this);
0034     }
0035 }
0036 
0037 SimpleIpListValidator::~SimpleIpListValidator() = default;
0038 
0039 QValidator::State SimpleIpListValidator::validate(QString &address, int &pos) const
0040 {
0041     Q_UNUSED(pos)
0042 
0043     // Split the incoming address on commas possibly with spaces on either side
0044     QStringList addressList = address.split(QStringLiteral(","));
0045 
0046     // Use a local variable for position in the validators so it doesn't screw
0047     // up the position of the cursor when we return
0048     int localPos = 0;
0049     QValidator::State result = QValidator::Acceptable;
0050 
0051     for (QString &rawAddr : addressList) {
0052         QValidator::State ipv4Result = QValidator::Acceptable;
0053         QValidator::State ipv6Result = QValidator::Acceptable;
0054 
0055         QString addr = rawAddr.trimmed();
0056 
0057         // If we are starting a new address and all the previous addresses
0058         // are not Acceptable then the previous addresses need to be completed
0059         // before a new one is started
0060         if (result != QValidator::Acceptable)
0061             return QValidator::Invalid;
0062 
0063         // See if it is an IPv4 address. If we are not testing for IPv4
0064         // then by definition IPv4 is Invalid
0065         if (m_ipv4Validator != nullptr)
0066             ipv4Result = m_ipv4Validator->validate(addr, localPos);
0067         else
0068             ipv4Result = QValidator::Invalid;
0069 
0070         // See if it is an IPv6 address. If we are not testing for IPv6
0071         // then by definition IPv6 is Invalid
0072         if (m_ipv6Validator != nullptr)
0073             ipv6Result = m_ipv6Validator->validate(addr, localPos);
0074         else
0075             ipv6Result = QValidator::Invalid;
0076 
0077         // If this address is not at least an Intermediate then get out because the list is Invalid
0078         if (ipv6Result == QValidator::Invalid && ipv4Result == QValidator::Invalid)
0079             return QValidator::Invalid;
0080 
0081         // If either validator judged this address to be Intermediate then that's the best the
0082         // final result can be for the whole list. No need to test for Acceptable because
0083         // that's the default set on entry and we only downgrade it from there.
0084         if (ipv4Result == QValidator::Intermediate || ipv6Result == QValidator::Intermediate)
0085             result = QValidator::Intermediate;
0086     }
0087     return result;
0088 }