File indexing completed on 2024-04-28 05:50:09

0001 /*
0002  * SPDX-License-Identifier: GPL-3.0-or-later
0003  * SPDX-FileCopyrightText: 2019-2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
0004  */
0005 
0006 #include "secretvalidator.h"
0007 
0008 #include "util.h"
0009 #include "../base32/base32.h"
0010 
0011 #include <QRegularExpression>
0012 #include <QString>
0013 
0014 static QValidator::State check_padding(int length)
0015 {
0016     if (length == 0) {
0017         return QValidator::Invalid;
0018     }
0019 
0020     switch (length % 8)
0021     {
0022     case 1:
0023     case 3:
0024     case 6:
0025         return QValidator::Intermediate;
0026     default:
0027         return QValidator::Acceptable;
0028     }
0029 }
0030 
0031 static const QRegularExpression& match_pattern(void)
0032 {
0033     static const QRegularExpression re(QLatin1String("^[A-Za-z2-7]+=*$"));
0034     re.optimize();
0035     return re;
0036 }
0037 
0038 namespace validators
0039 {
0040     Base32Validator::Base32Validator(QObject *parent):
0041         QValidator(parent),
0042         m_pattern(match_pattern())
0043     {
0044     }
0045 
0046     void Base32Validator::fixup(QString &input) const
0047     {
0048         input = validators::strip_spaces(input);
0049         input = input.toUpper();
0050         m_pattern.fixup(input);
0051 
0052         int length = input.endsWith(QLatin1Char('='))
0053             ? input.indexOf(QLatin1Char('='))
0054             : input.size();
0055 
0056         QString fixed = input.left(length);
0057         QValidator::State result = check_padding(length);
0058 
0059         if (result == QValidator::Acceptable) {
0060             QString maybeFixed = fixed;
0061             while ((maybeFixed.size() % 8) != 0) {
0062                 maybeFixed += QLatin1Char('=');
0063             }
0064 
0065             if (base32::validate(maybeFixed)) {
0066                 fixed = maybeFixed;
0067             }
0068         }
0069 
0070         input = fixed;
0071     }
0072 
0073     QValidator::State Base32Validator::validate(QString &input, int &cursor) const
0074     {
0075         QValidator::State s = m_pattern.validate(input, cursor);
0076         if (s == QValidator::Acceptable) {
0077             // if the basics are covered, check the padding & alignment
0078             return base32::validate(input) ? QValidator::Acceptable : QValidator::Intermediate;
0079         } else {
0080             return s;
0081         }
0082     }
0083 }