From 24db645167b42adba5d9c221215be83bef39e2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 3 Jun 2015 21:57:22 +0200 Subject: NOISSUE sanitize Json Removes magical parameter madness. All require* can throw All ensure* need a default value and never throw --- logic/Json.h | 119 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 68 insertions(+), 51 deletions(-) (limited to 'logic/Json.h') diff --git a/logic/Json.h b/logic/Json.h index 9f4c5445..55f0cfc1 100644 --- a/logic/Json.h +++ b/logic/Json.h @@ -18,11 +18,6 @@ namespace Json { DECLARE_EXCEPTION(Json); -enum Requirement -{ - Required -}; - /// @throw FileSystemException void write(const QJsonDocument &doc, const QString &filename); /// @throw FileSystemException @@ -36,13 +31,13 @@ QByteArray toText(const QJsonObject &obj); QByteArray toText(const QJsonArray &array); /// @throw JsonException -QJsonDocument ensureDocument(const QByteArray &data, const QString &what = "Document"); +QJsonDocument requireDocument(const QByteArray &data, const QString &what = "Document"); /// @throw JsonException -QJsonDocument ensureDocument(const QString &filename, const QString &what = "Document"); +QJsonDocument requireDocument(const QString &filename, const QString &what = "Document"); /// @throw JsonException -QJsonObject ensureObject(const QJsonDocument &doc, const QString &what = "Document"); +QJsonObject requireObject(const QJsonDocument &doc, const QString &what = "Document"); /// @throw JsonException -QJsonArray ensureArray(const QJsonDocument &doc, const QString &what = "Document"); +QJsonArray requireArray(const QJsonDocument &doc, const QString &what = "Document"); /////////////////// WRITING //////////////////// @@ -107,22 +102,36 @@ QJsonArray toJsonArray(const QList &container) ////////////////// READING //////////////////// +/// @throw JsonException template -T ensureIsType(const QJsonValue &value, const Requirement requirement = Required, const QString &what = "Value"); - -template<> double ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> bool ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> int ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QJsonObject ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QJsonArray ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QJsonValue ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QByteArray ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QDateTime ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QVariant ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QString ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QUuid ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QDir ensureIsType(const QJsonValue &value, const Requirement, const QString &what); -template<> QUrl ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +T requireIsType(const QJsonValue &value, const QString &what = "Value"); + +/// @throw JsonException +template<> double requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> bool requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> int requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QJsonObject requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QJsonArray requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QJsonValue requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QByteArray requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QDateTime requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QVariant requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QString requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QUuid requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QDir requireIsType(const QJsonValue &value, const QString &what); +/// @throw JsonException +template<> QUrl requireIsType(const QJsonValue &value, const QString &what); // the following functions are higher level functions, that make use of the above functions for // type conversion @@ -133,26 +142,30 @@ T ensureIsType(const QJsonValue &value, const T default_, const QString &what = { return default_; } - return ensureIsType(value, Required, what); + try + { + return requireIsType(value, what); + } + catch (JsonException &) + { + return default_; + } } /// @throw JsonException template -T ensureIsType(const QJsonObject &parent, const QString &key, - const Requirement requirement = Required, - const QString &what = "__placeholder__") +T requireIsType(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") { const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); if (!parent.contains(key)) { throw JsonException(localWhat + "s parent does not contain " + localWhat); } - return ensureIsType(parent.value(key), requirement, localWhat); + return requireIsType(parent.value(key), localWhat); } template -T ensureIsType(const QJsonObject &parent, const QString &key, const T default_, - const QString &what = "__placeholder__") +T ensureIsType(const QJsonObject &parent, const QString &key, const T default_, const QString &what = "__placeholder__") { const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); if (!parent.contains(key)) @@ -163,53 +176,49 @@ T ensureIsType(const QJsonObject &parent, const QString &key, const T default_, } template -QList ensureIsArrayOf(const QJsonDocument &doc) +QList requireIsArrayOf(const QJsonDocument &doc) { - const QJsonArray array = ensureArray(doc); + const QJsonArray array = requireArray(doc); QList out; for (const QJsonValue val : array) { - out.append(ensureIsType(val, Required, "Document")); + out.append(requireIsType(val, "Document")); } return out; } template -QList ensureIsArrayOf(const QJsonValue &value, const Requirement = Required, - const QString &what = "Value") +QList ensureIsArrayOf(const QJsonValue &value, const QString &what = "Value") { - const QJsonArray array = ensureIsType(value, Required, what); + const QJsonArray array = requireIsType(value, what); QList out; for (const QJsonValue val : array) { - out.append(ensureIsType(val, Required, what)); + out.append(ensureIsType(val, what)); } return out; } template -QList ensureIsArrayOf(const QJsonValue &value, const QList default_, - const QString &what = "Value") +QList ensureIsArrayOf(const QJsonValue &value, const QList default_, const QString &what = "Value") { if (value.isUndefined()) { return default_; } - return ensureIsArrayOf(value, Required, what); + return ensureIsArrayOf(value, what); } /// @throw JsonException template -QList ensureIsArrayOf(const QJsonObject &parent, const QString &key, - const Requirement requirement = Required, - const QString &what = "__placeholder__") +QList requireIsArrayOf(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") { const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); if (!parent.contains(key)) { throw JsonException(localWhat + "s parent does not contain " + localWhat); } - return ensureIsArrayOf(parent.value(key), requirement, localWhat); + return requireIsArrayOf(parent.value(key), localWhat); } template @@ -226,14 +235,22 @@ QList ensureIsArrayOf(const QJsonObject &parent, const QString &key, // this macro part could be replaced by variadic functions that just pass on their arguments, but that wouldn't work well with IDE helpers #define JSON_HELPERFUNCTIONS(NAME, TYPE) \ - inline TYPE ensure##NAME(const QJsonValue &value, const Requirement requirement = Required, const QString &what = "Value") \ -{ return ensureIsType(value, requirement, what); } \ + inline TYPE require##NAME(const QJsonValue &value, const QString &what = "Value") \ + { \ + return requireIsType(value, what); \ + } \ inline TYPE ensure##NAME(const QJsonValue &value, const TYPE default_, const QString &what = "Value") \ -{ return ensureIsType(value, default_, what); } \ - inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const Requirement requirement = Required, const QString &what = "__placeholder__") \ -{ return ensureIsType(parent, key, requirement, what); } \ + { \ + return ensureIsType(value, default_, what); \ + } \ + inline TYPE require##NAME(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") \ + { \ + return requireIsType(parent, key, what); \ + } \ inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const TYPE default_, const QString &what = "__placeholder") \ -{ return ensureIsType(parent, key, default_, what); } + { \ + return ensureIsType(parent, key, default_, what); \ + } JSON_HELPERFUNCTIONS(Array, QJsonArray) JSON_HELPERFUNCTIONS(Object, QJsonObject) -- cgit v1.2.3