File indexing completed on 2024-12-01 08:10:07
0001 /* 0002 SPDX-FileCopyrightText: 2009 Paul Marchouk <pmarchouk@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "simpleipv4addressvalidator.h" 0008 0009 #include <QList> 0010 #include <QStringList> 0011 0012 SimpleIpV4AddressValidator::SimpleIpV4AddressValidator(AddressStyle style, QObject *parent) 0013 : QValidator(parent) 0014 , m_addressStyle(style) 0015 { 0016 switch (style) { 0017 case Base: 0018 m_validator.setRegularExpression(QRegularExpression(QStringLiteral("[0-9, ]{1,3}\\.[0-9, ]{1,3}\\.[0-9, ]{1,3}\\.[0-9, ]{1,3}"))); 0019 break; 0020 case WithCidr: 0021 m_validator.setRegularExpression(QRegularExpression(QStringLiteral("([0-9]{1,3}\\.){3,3}[0-9]{1,3}/[0-9]{1,2}"))); 0022 break; 0023 case WithPort: 0024 m_validator.setRegularExpression(QRegularExpression(QStringLiteral("([0-9]{1,3}\\.){3,3}[0-9]{1,3}:[0-9]{1,5}"))); 0025 break; 0026 } 0027 } 0028 0029 SimpleIpV4AddressValidator::~SimpleIpV4AddressValidator() = default; 0030 0031 QValidator::State SimpleIpV4AddressValidator::validate(QString &address, int &pos) const 0032 { 0033 QValidator::State maskResult = checkWithInputMask(address, pos); 0034 if (QValidator::Invalid == maskResult) { 0035 return QValidator::Invalid; 0036 } 0037 0038 // this list will be filled with tetrad values. It can be used to make 0039 // some additional correctness checks on the last validation step. 0040 QList<int> tetrads; 0041 0042 QValidator::State tetradResult = checkTetradsRanges(address, tetrads); 0043 if (QValidator::Invalid == tetradResult) 0044 return QValidator::Invalid; 0045 else if (QValidator::Intermediate == tetradResult || QValidator::Intermediate == maskResult) 0046 return QValidator::Intermediate; 0047 else 0048 return QValidator::Acceptable; 0049 } 0050 0051 QValidator::State SimpleIpV4AddressValidator::checkWithInputMask(QString &value, int &pos) const 0052 { 0053 return m_validator.validate(value, pos); 0054 } 0055 0056 QValidator::State SimpleIpV4AddressValidator::checkTetradsRanges(QString &value, QList<int> &tetrads) const 0057 { 0058 QStringList temp; 0059 QList<QStringView> addrParts; 0060 QStringList cidrParts; 0061 QStringList portParts; 0062 0063 switch (m_addressStyle) { 0064 case Base: 0065 addrParts = QStringView(value).split(QLatin1Char('.')); 0066 break; 0067 0068 case WithCidr: 0069 cidrParts = value.split(QLatin1Char('/')); 0070 addrParts = QStringView(cidrParts[0]).split(QLatin1Char('.')); 0071 break; 0072 0073 case WithPort: 0074 portParts = value.split(QLatin1Char(':')); 0075 addrParts = QStringView(portParts[0]).split(QLatin1Char('.')); 0076 break; 0077 } 0078 0079 int i = 0; 0080 // fill in the list with invalid values 0081 tetrads << -1 << -1 << -1 << -1; 0082 0083 // lets check address parts 0084 for (const QStringView &part : std::as_const(addrParts)) { 0085 if (part.isEmpty()) { 0086 if (i != (addrParts.size() - 1)) { 0087 // qCDebug(PLASMA_NM_EDITOR_LOG) << "part.isEmpty()"; 0088 return QValidator::Invalid; 0089 } 0090 // the last tetrad can be empty, continue... 0091 return QValidator::Intermediate; 0092 } 0093 0094 tetrads[i] = part.toInt(); 0095 0096 if (tetrads[i] > 255) { 0097 // qCDebug(PLASMA_NM_EDITOR_LOG) << "tetrads[i] > 255"; 0098 return QValidator::Invalid; 0099 } 0100 0101 // correct tetrad value: for example, 001 -> 1 0102 temp.append(QString::number(tetrads[i])); 0103 0104 i++; 0105 } 0106 0107 // replace input string with the corrected version 0108 value = temp.join(QLatin1String(".")); 0109 0110 if (i < 4) { 0111 // not all tetrads are filled... continue 0112 // qCDebug(PLASMA_NM_EDITOR_LOG) << "QValidator::Intermediate"; 0113 return QValidator::Intermediate; 0114 } else { 0115 if (m_addressStyle == WithCidr) { 0116 if (cidrParts.size() > 1) { 0117 value += QLatin1String("/"); 0118 if (!cidrParts[1].isEmpty()) { 0119 int cidrValue = cidrParts[1].toInt(); 0120 if (cidrValue > 32) { 0121 return QValidator::Invalid; 0122 } else { 0123 value += cidrParts[1]; 0124 return QValidator::Acceptable; 0125 } 0126 } else { 0127 return QValidator::Intermediate; 0128 } 0129 } 0130 } else if (m_addressStyle == WithPort) { 0131 if (portParts.size() > 1) { 0132 value += QLatin1String(":"); 0133 if (!portParts[1].isEmpty()) { 0134 int portValue = portParts[1].toInt(); 0135 if (portValue > 65535) { 0136 return QValidator::Invalid; 0137 } else { 0138 value += portParts[1]; 0139 return QValidator::Acceptable; 0140 } 0141 } else { 0142 return QValidator::Intermediate; 0143 } 0144 } 0145 } 0146 0147 // qCDebug(PLASMA_NM_EDITOR_LOG) << "QValidator::Acceptable"; 0148 return QValidator::Acceptable; 0149 } 0150 } 0151 0152 #include "moc_simpleipv4addressvalidator.cpp"