summaryrefslogtreecommitdiffstats
path: root/src/tools/moc/moc.cpp
diff options
context:
space:
mode:
authorAhmad Samir <a.samirh78@gmail.com>2023-05-25 19:22:05 +0300
committerAhmad Samir <a.samirh78@gmail.com>2023-06-06 01:23:01 +0300
commit88de6960747aa567c6947913f9e5715cfb972d46 (patch)
treee75a70bb6cbdb00f16a6f20a28832bd49601700f /src/tools/moc/moc.cpp
parent2cca2323d3919e4ffd2c447bb7ba69ef5a7c9aaa (diff)
Moc: check sizes of specific member QLists are within INT_MAX range
Parts of the public API, e.g. QMetaMethod::methodIndex and similar functions return int, and other parts of the code expect int values, at least for Qt6 this can't be changed, so use qsizetype internally and assert the values fit in an int. As pointed out in code review, not many people will build moc in debug mode, so asserts aren't that useful here. Instead print error messages and exit, like is already done in other parts of the code. Change-Id: Id305165caa996c899f30770a757098fe2f9a96f6 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/tools/moc/moc.cpp')
-rw-r--r--src/tools/moc/moc.cpp49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index f8c36a5abd..39fc5ca466 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -318,6 +318,9 @@ void Moc::parseFunctionArguments(FunctionDef *def)
def->arguments.removeLast();
def->isRawSlot = true;
}
+
+ if (Q_UNLIKELY(def->arguments.size() >= std::numeric_limits<int>::max()))
+ error("number of function arguments exceeds std::numeric_limits<int>::max()");
}
bool Moc::testFunctionAttribute(FunctionDef *def)
@@ -603,6 +606,42 @@ void Moc::prependNamespaces(BaseDef &def, const QList<NamespaceDef> &namespaceLi
}
}
+void Moc::checkListSizes(const ClassDef &def)
+{
+ if (Q_UNLIKELY(def.nonClassSignalList.size() > std::numeric_limits<int>::max()))
+ error("number of signals defined in parent class(es) exceeds "
+ "std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.propertyList.size() > std::numeric_limits<int>::max()))
+ error("number of bindable properties exceeds std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.classInfoList.size() > std::numeric_limits<int>::max()))
+ error("number of times Q_CLASSINFO macro is used exceeds "
+ "std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.enumList.size() > std::numeric_limits<int>::max()))
+ error("number of enumerations exceeds std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.superclassList.size() > std::numeric_limits<int>::max()))
+ error("number of super classes exceeds std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.constructorList.size() > std::numeric_limits<int>::max()))
+ error("number of constructor parameters exceeds std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.signalList.size() > std::numeric_limits<int>::max()))
+ error("number of signals exceeds std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.slotList.size() > std::numeric_limits<int>::max()))
+ error("number of declared slots exceeds std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.methodList.size() > std::numeric_limits<int>::max()))
+ error("number of methods exceeds std::numeric_limits<int>::max().");
+
+ if (Q_UNLIKELY(def.publicList.size() > std::numeric_limits<int>::max()))
+ error("number of public functions declared in this class exceeds "
+ "std::numeric_limits<int>::max().");
+}
+
void Moc::parse()
{
QList<NamespaceDef> namespaceList;
@@ -974,6 +1013,8 @@ void Moc::parse()
checkProperties(&def);
+ checkListSizes(def);
+
classList += def;
QHash<QByteArray, QByteArray> &classHash = def.hasQObject ? knownQObjectClasses : knownGadgets;
classHash.insert(def.classname, def.qualified);
@@ -993,8 +1034,10 @@ void Moc::parse()
if (it != classList.end()) {
it->classInfoList += def.classInfoList;
+ Q_ASSERT(it->classInfoList.size() <= std::numeric_limits<int>::max());
it->enumDeclarations.insert(def.enumDeclarations);
it->enumList += def.enumList;
+ Q_ASSERT(it->enumList.size() <= std::numeric_limits<int>::max());
it->flagAliases.insert(def.flagAliases);
} else {
knownGadgets.insert(def.classname, def.qualified);
@@ -1915,7 +1958,7 @@ void Moc::checkProperties(ClassDef *cdef)
}
if (!p.notify.isEmpty()) {
int notifyId = -1;
- for (int j = 0; j < cdef->signalList.size(); ++j) {
+ for (int j = 0; j < int(cdef->signalList.size()); ++j) {
const FunctionDef &f = cdef->signalList.at(j);
if (f.name != p.notify) {
continue;
@@ -1926,10 +1969,10 @@ void Moc::checkProperties(ClassDef *cdef)
}
p.notifyId = notifyId;
if (notifyId == -1) {
- int index = cdef->nonClassSignalList.indexOf(p.notify);
+ const int index = int(cdef->nonClassSignalList.indexOf(p.notify));
if (index == -1) {
cdef->nonClassSignalList << p.notify;
- p.notifyId = -1 - cdef->nonClassSignalList.size();
+ p.notifyId = int(-1 - cdef->nonClassSignalList.size());
} else {
p.notifyId = -2 - index;
}