Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
validator.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "validator.h"
5#include "driver.h"
6#include "ui4.h"
7#include "uic.h"
8
9#include <qstringview.h>
10
12
13using namespace Qt::StringLiterals;
14
15// An approximation of "Unicode Standard Annex #31" for checking property
16// and enumeration identifiers to prevent code injection attacks.
17// FIXME 6.9: Simplify according to QTBUG-126860
18static bool isIdStart(QChar c)
19{
20 bool result = false;
21 switch (c.category()) {
22 case QChar::Letter_Uppercase:
23 case QChar::Letter_Lowercase:
24 case QChar::Letter_Titlecase:
25 case QChar::Letter_Modifier:
26 case QChar::Letter_Other:
27 case QChar::Number_Letter:
28 result = true;
29 break;
30 default:
31 result = c == u'_';
32 break;
33 }
34 return result;
35}
36
37static bool isIdContinuation(QChar c)
38{
39 bool result = false;
40 switch (c.category()) {
41 case QChar::Letter_Uppercase:
42 case QChar::Letter_Lowercase:
43 case QChar::Letter_Titlecase:
44 case QChar::Letter_Modifier:
45 case QChar::Letter_Other:
46 case QChar::Number_Letter:
47 case QChar::Mark_NonSpacing:
48 case QChar::Mark_SpacingCombining:
49 case QChar::Number_DecimalDigit:
50 case QChar::Punctuation_Connector: // '_'
51 result = true;
52 break;
53 default:
54 break;
55 }
56 return result;
57}
58
59static bool isEnumIdContinuation(QChar c)
60{
61 return c == u':' || c == u'|' || c == u' ' || isIdContinuation(c);
62}
63
65{
66 return !name.isEmpty() && isIdStart(name.at(0))
67 && std::all_of(name.cbegin() + 1, name.cend(), isIdContinuation);
68}
69
70static bool checkEnumValue(QStringView name)
71{
72 return !name.isEmpty() && isIdStart(name.at(0))
73 && std::all_of(name.cbegin() + 1, name.cend(), isEnumIdContinuation);
74}
75
76static bool isClassNameContinuation(QChar c)
77{
78 return c == u':' || c == u'.' || isIdContinuation(c);
79}
80
81static bool checkClassName(QStringView name)
82{
83 return !name.isEmpty() && isIdStart(name.at(0))
84 && std::all_of(name.cbegin() + 1, name.cend(), isClassNameContinuation);
85}
86
87static QString msgInvalidValue(const QString &name, const QString &value)
88{
89 return "Invalid property value: \""_L1 + name + "\": \""_L1 + value + u'"';
90}
91
92static QString msgInvalidPropertyName(const QString &name)
93{
94 return "Invalid property name: \""_L1 + name + u'"';
95}
96
97static QString msgInvalidClassName(const QString &name)
98{
99 return "Invalid class name: \""_L1 + name + u'"';
100}
101
102static QString msgInvalidPixmapFunction(const QString &name)
103{
104 return "Invalid pixmap function name: \""_L1 + name + u'"';
105}
106
107static void checkProperties(const QList<DomProperty *> &properties, QStringList *errors)
108{
109 for (const DomProperty *p : properties) {
110 const bool isDynamicProperty = p->hasAttributeStdset() && p->attributeStdset() == 0;
111 const QString &name = p->attributeName();
112 if (!isDynamicProperty && !checkPropertyName(name))
113 errors->append(msgInvalidPropertyName(name));
114 switch (p->kind()) {
115 case DomProperty::Set:
116 if (!checkEnumValue(p->elementSet()))
117 errors->append(msgInvalidValue(name, p->elementSet()));
118 break;
119 case DomProperty::Enum:
120 if (!checkEnumValue(p->elementEnum()))
121 errors->append(msgInvalidValue(name, p->elementEnum()));
122 default:
123 break;
124 }
125 }
126}
127
129 m_driver(uic->driver())
130{
131}
132
133void Validator::acceptUI(DomUI *node)
134{
136
137 if (!checkClassName(node->elementClass()))
138 m_errors.append(msgInvalidClassName(node->elementClass()));
139
140 if (node->hasElementPixmapFunction()) {
141 const QString &pixmapFunction = node->elementPixmapFunction();
142 // Accommodate for legacy forms with empty entries
143 if (!pixmapFunction.isEmpty() && !checkClassName(pixmapFunction))
144 m_errors.append(msgInvalidPixmapFunction(node->elementPixmapFunction()));
145 }
146}
147
148void Validator::acceptWidget(DomWidget *node)
149{
150 (void) m_driver->findOrInsertWidget(node);
151
152 checkProperties(node->elementProperty(), &m_errors);
153
154 if (!checkClassName(node->attributeClass()))
155 m_errors.append(msgInvalidClassName(node->attributeClass()));
156
158}
159
160void Validator::acceptLayoutItem(DomLayoutItem *node)
161{
162 (void) m_driver->findOrInsertLayoutItem(node);
163
165}
166
167void Validator::acceptLayout(DomLayout *node)
168{
169 (void) m_driver->findOrInsertLayout(node);
170
171 checkProperties(node->elementProperty(), &m_errors);
172
174}
175
176void Validator::acceptActionGroup(DomActionGroup *node)
177{
178 (void) m_driver->findOrInsertActionGroup(node);
179
180 checkProperties(node->elementProperty(), &m_errors);
181
183}
184
185void Validator::acceptAction(DomAction *node)
186{
187 (void) m_driver->findOrInsertAction(node);
188
189 checkProperties(node->elementProperty(), &m_errors);
190
192}
193
194QT_END_NAMESPACE
QString findOrInsertWidget(const DomWidget *ui_widget)
Definition driver.cpp:65
QString findOrInsertActionGroup(const DomActionGroup *ui_group)
Definition driver.cpp:100
QString findOrInsertLayoutItem(const DomLayoutItem *ui_layoutItem)
Definition driver.cpp:82
QString findOrInsertAction(const DomAction *ui_action)
Definition driver.cpp:105
QString findOrInsertLayout(const DomLayout *ui_layout)
Definition driver.cpp:77
Definition qlist.h:81
\inmodule QtCore
Definition qstringview.h:77
Definition uic.h:30
Driver * driver() const
Definition uic.h:38
Combined button and popup list for selecting options.
static bool isEnumIdContinuation(QChar c)
Definition validator.cpp:59
static QString msgInvalidValue(const QString &name, const QString &value)
Definition validator.cpp:87
static bool checkClassName(QStringView name)
Definition validator.cpp:81
static bool isIdStart(QChar c)
Definition validator.cpp:18
static bool checkEnumValue(QStringView name)
Definition validator.cpp:70
static void checkProperties(const QList< DomProperty * > &properties, QStringList *errors)
static bool checkPropertyName(QStringView name)
Definition validator.cpp:64
static bool isIdContinuation(QChar c)
Definition validator.cpp:37
static QString msgInvalidClassName(const QString &name)
Definition validator.cpp:97
static bool isClassNameContinuation(QChar c)
Definition validator.cpp:76
static QString msgInvalidPropertyName(const QString &name)
Definition validator.cpp:92
static QString msgInvalidPixmapFunction(const QString &name)
virtual void acceptAction(DomAction *action)
virtual void acceptActionGroup(DomActionGroup *actionGroup)
virtual void acceptLayoutItem(DomLayoutItem *layoutItem)
virtual void acceptWidget(DomWidget *widget)
virtual void acceptUI(DomUI *ui)
Definition treewalker.cpp:9
virtual void acceptLayout(DomLayout *layout)
void acceptUI(DomUI *node) override
void acceptLayoutItem(DomLayoutItem *node) override
Validator(Uic *uic)
void acceptWidget(DomWidget *node) override
void acceptLayout(DomLayout *node) override
void acceptAction(DomAction *node) override
void acceptActionGroup(DomActionGroup *node) override