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 void checkProperties(const QList<DomProperty *> &properties, QStringList *errors)
103{
104 for (const DomProperty *p : properties) {
105 const bool isDynamicProperty = p->hasAttributeStdset() && p->attributeStdset() == 0;
106 const QString &name = p->attributeName();
107 if (!isDynamicProperty && !checkPropertyName(name))
108 errors->append(msgInvalidPropertyName(name));
109 switch (p->kind()) {
110 case DomProperty::Set:
111 if (!checkEnumValue(p->elementSet()))
112 errors->append(msgInvalidValue(name, p->elementSet()));
113 break;
114 case DomProperty::Enum:
115 if (!checkEnumValue(p->elementEnum()))
116 errors->append(msgInvalidValue(name, p->elementEnum()));
117 default:
118 break;
119 }
120 }
121}
122
124 m_driver(uic->driver())
125{
126}
127
128void Validator::acceptUI(DomUI *node)
129{
131
132 if (!checkClassName(node->elementClass()))
133 m_errors.append(msgInvalidClassName(node->elementClass()));
134}
135
136void Validator::acceptWidget(DomWidget *node)
137{
138 (void) m_driver->findOrInsertWidget(node);
139
140 checkProperties(node->elementProperty(), &m_errors);
141
142 if (!checkClassName(node->attributeClass()))
143 m_errors.append(msgInvalidClassName(node->attributeClass()));
144
146}
147
148void Validator::acceptLayoutItem(DomLayoutItem *node)
149{
150 (void) m_driver->findOrInsertLayoutItem(node);
151
153}
154
155void Validator::acceptLayout(DomLayout *node)
156{
157 (void) m_driver->findOrInsertLayout(node);
158
159 checkProperties(node->elementProperty(), &m_errors);
160
162}
163
164void Validator::acceptActionGroup(DomActionGroup *node)
165{
166 (void) m_driver->findOrInsertActionGroup(node);
167
168 checkProperties(node->elementProperty(), &m_errors);
169
171}
172
173void Validator::acceptAction(DomAction *node)
174{
175 (void) m_driver->findOrInsertAction(node);
176
177 checkProperties(node->elementProperty(), &m_errors);
178
180}
181
182QT_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
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