Cutelee  6.2.0
stringfilters.cpp
1 /*
2  This file is part of the Cutelee template system.
3 
4  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either version
9  2.1 of the Licence, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 #include "stringfilters.h"
22 
23 #include "util.h"
24 
25 #include <QtCore/QRegularExpression>
26 #include <QtCore/QVariant>
27 #include <QtCore/QJsonArray>
28 #include <QtCore/QJsonObject>
29 #include <QtCore/QJsonDocument>
30 
32  const QVariant &argument,
33  bool autoescape) const
34 {
35  Q_UNUSED(argument)
36  Q_UNUSED(autoescape)
37  auto safeString = getSafeString(input);
38  safeString.get()
39  .replace(QLatin1Char('\\'), QStringLiteral("\\\\"))
40  .get()
41  .replace(QLatin1Char('\"'), QStringLiteral("\\\""))
42  .get()
43  .replace(QLatin1Char('\''), QStringLiteral("\\\'"));
44  return safeString;
45 }
46 
48  const QVariant &argument,
49  bool autoescape) const
50 {
51  Q_UNUSED(argument)
52  Q_UNUSED(autoescape)
53  auto safeString = getSafeString(input);
54  if (safeString.get().isEmpty())
55  return QString();
56 
57  return QVariant(safeString.get().at(0).toUpper()
58  + static_cast<QString>(
59  safeString.get().right(safeString.get().size() - 1)));
60 }
61 
62 EscapeJsFilter::EscapeJsFilter() {}
63 
64 static QList<std::pair<QString, QString>> getJsEscapes()
65 {
67  jsEscapes << std::pair<QString, QString>(QChar::fromLatin1('\\'),
68  QStringLiteral("\\u005C"))
69  << std::pair<QString, QString>(QChar::fromLatin1('\''),
70  QStringLiteral("\\u0027"))
71  << std::pair<QString, QString>(QChar::fromLatin1('\"'),
72  QStringLiteral("\\u0022"))
73  << std::pair<QString, QString>(QChar::fromLatin1('>'),
74  QStringLiteral("\\u003E"))
75  << std::pair<QString, QString>(QChar::fromLatin1('<'),
76  QStringLiteral("\\u003C"))
77  << std::pair<QString, QString>(QChar::fromLatin1('&'),
78  QStringLiteral("\\u0026"))
79  << std::pair<QString, QString>(QChar::fromLatin1('='),
80  QStringLiteral("\\u003D"))
81  << std::pair<QString, QString>(QChar::fromLatin1('-'),
82  QStringLiteral("\\u002D"))
83  << std::pair<QString, QString>(QChar::fromLatin1(';'),
84  QStringLiteral("\\u003B"))
85  << std::pair<QString, QString>(QChar(0x2028), QStringLiteral("\\u2028"))
86  << std::pair<QString, QString>(QChar(0x2029),
87  QStringLiteral("\\u2029"));
88 
89  for (auto i = 0; i < 32; ++i) {
90  jsEscapes << std::pair<QString, QString>(
91  QChar(i),
92  QStringLiteral("\\u00")
93  + QStringLiteral("%1").arg(i, 2, 16, QLatin1Char('0')).toUpper());
94  }
95  return jsEscapes;
96 }
97 
99  const QVariant &argument,
100  bool autoescape) const
101 {
102  Q_UNUSED(argument)
103  Q_UNUSED(autoescape)
104  QString retString = getSafeString(input);
105 
106  static const auto jsEscapes = getJsEscapes();
107 
108  for (auto &escape : jsEscapes) {
109  retString = retString.replace(escape.first, escape.second);
110  }
111  return retString;
112 }
113 
115  const QVariant &argument,
116  bool autoescape) const
117 {
118  Q_UNUSED(argument)
119  Q_UNUSED(autoescape)
120  auto safeString = getSafeString(input);
121 
122  const QRegularExpression fixAmpersandsRegexp(
123  QStringLiteral("&(?!(\\w+|#\\d+);)"));
124 
125  safeString.get().replace(fixAmpersandsRegexp, QStringLiteral("&amp;"));
126 
127  return safeString;
128 }
129 
130 QVariant CutFilter::doFilter(const QVariant &input, const QVariant &argument,
131  bool autoescape) const
132 {
133  Q_UNUSED(autoescape)
134  auto retString = getSafeString(input);
135  auto argString = getSafeString(argument);
136 
137  auto inputSafe = retString.isSafe();
138 
139  retString.get().remove(argString);
140 
141  if (inputSafe && argString.get() != QChar::fromLatin1(';'))
142  return SafeString(retString, true);
143  else
144  return retString;
145 }
146 
147 QVariant SafeFilter::doFilter(const QVariant &input, const QVariant &argument,
148  bool autoescape) const
149 {
150  Q_UNUSED(argument)
151  Q_UNUSED(autoescape)
152  return markSafe(getSafeString(input));
153 }
154 
156  const QVariant &argument,
157  bool autoescape) const
158 {
159  Q_UNUSED(argument)
160  auto safeString = getSafeString(input);
161  auto lines = safeString.get().split(QLatin1Char('\n'));
162  auto width = QString::number(lines.size()).size();
163 
164  const auto shouldEscape = (autoescape && !safeString.isSafe());
165  for (auto i = 0; i < lines.size(); ++i) {
166  lines[i]
167  = QStringLiteral("%1. %2")
168  .arg(i + 1, width)
169  .arg(shouldEscape ? QString(escape(lines.at(i))) : lines.at(i));
170  }
171 
172  return SafeString(lines.join(QChar::fromLatin1('\n')), true);
173 }
174 
175 QVariant LowerFilter::doFilter(const QVariant &input, const QVariant &argument,
176  bool autoescape) const
177 {
178  Q_UNUSED(argument)
179  Q_UNUSED(autoescape)
180  return getSafeString(input).get().toLower();
181 }
182 
184  const QVariant &argument,
185  bool autoescape) const
186 {
187  Q_UNUSED(autoescape)
188  SafeString a;
189  if (isSafeString(input))
190  a = getSafeString(input);
191  else if (input.userType() == qMetaTypeId<QVariantList>()) {
192  a = toString(input.value<QVariantList>());
193  }
194 
195  return SafeString(getSafeString(argument).get().arg(a),
196  getSafeString(input).isSafe());
197 }
198 
199 QVariant TitleFilter::doFilter(const QVariant &input, const QVariant &argument,
200  bool autoescape) const
201 {
202  Q_UNUSED(argument)
203  Q_UNUSED(autoescape)
204 
205  QString str = getSafeString(input);
206 
207  auto it = str.begin();
208  const auto end = str.end();
209 
210  auto toUpper = true;
211  for (; it != end; ++it) {
212  if (toUpper)
213  *it = it->toUpper();
214  else
215  *it = it->toLower();
216  toUpper = it->isSpace();
217  }
218 
219  return str;
220 }
221 
223  const QVariant &argument,
224  bool autoescape) const
225 {
226  Q_UNUSED(autoescape)
227  auto s = getSafeString(argument);
228 
229  bool ok;
230  auto numWords = s.get().toInt(&ok);
231 
232  if (!ok) {
233  return input.toString();
234  }
235 
236  QString inputString = getSafeString(input);
237  auto words = inputString.split(QLatin1Char(' '), Qt::SkipEmptyParts);
238 
239  if (words.size() > numWords) {
240  words = words.mid(0, numWords);
241  if (!words.at(words.size() - 1).endsWith(QStringLiteral("..."))) {
242  words << QStringLiteral("...");
243  }
244  }
245  return words.join(QChar::fromLatin1(' '));
246 }
247 
248 QVariant UpperFilter::doFilter(const QVariant &input, const QVariant &argument,
249  bool autoescape) const
250 {
251  Q_UNUSED(argument)
252  Q_UNUSED(autoescape)
253  return getSafeString(input).get().toUpper();
254 }
255 
257  const QVariant &argument,
258  bool autoescape) const
259 {
260  Q_UNUSED(argument)
261  Q_UNUSED(autoescape)
262  return QString::number(
263  getSafeString(input).get().split(QLatin1Char(' ')).size());
264 }
265 
266 QVariant LJustFilter::doFilter(const QVariant &input, const QVariant &argument,
267  bool autoescape) const
268 {
269  Q_UNUSED(autoescape)
270  return getSafeString(input).get().leftJustified(
271  getSafeString(argument).get().toInt());
272 }
273 
274 QVariant RJustFilter::doFilter(const QVariant &input, const QVariant &argument,
275  bool autoescape) const
276 {
277  Q_UNUSED(autoescape)
278  return getSafeString(input).get().rightJustified(
279  getSafeString(argument).get().toInt());
280 }
281 
282 QVariant CenterFilter::doFilter(const QVariant &input, const QVariant &argument,
283  bool autoescape) const
284 {
285  Q_UNUSED(autoescape)
286  QString value = getSafeString(input);
287  const auto valueWidth = value.size();
288  const auto width = getSafeString(argument).get().toInt();
289  const auto totalPadding = width - valueWidth;
290  const auto rightPadding = totalPadding >> 1;
291 
292  return value.leftJustified(valueWidth + rightPadding).rightJustified(width);
293 }
294 
295 QVariant EscapeFilter::doFilter(const QVariant &input, const QVariant &argument,
296  bool autoescape) const
297 {
298  Q_UNUSED(argument)
299  Q_UNUSED(autoescape)
300  return markForEscaping(getSafeString(input));
301 }
302 
304  const QVariant &argument,
305  bool autoescape) const
306 {
307  Q_UNUSED(argument)
308  Q_UNUSED(autoescape)
309  return markSafe(escape(getSafeString(input)));
310 }
311 
313  const QVariant &argument,
314  bool autoescape) const
315 {
316  Q_UNUSED(autoescape)
317  const auto tags = getSafeString(argument).get().split(QLatin1Char(' '));
318  const auto tagRe
319  = QStringLiteral("(%1)").arg(tags.join(QChar::fromLatin1('|')));
320  const QRegularExpression startTag(
321  QStringLiteral("<%1(/?>|(\\s+[^>]*>))").arg(tagRe));
322  const QRegularExpression endTag(QStringLiteral("</%1>").arg(tagRe));
323 
324  auto value = getSafeString(input);
325  const auto safeInput = value.isSafe();
326  value.get().remove(startTag);
327  value.get().remove(endTag);
328  if (safeInput)
329  return markSafe(value);
330  return value;
331 }
332 
334  const QVariant &argument,
335  bool autoescape) const
336 {
337  Q_UNUSED(argument)
338  Q_UNUSED(autoescape)
339  static QRegularExpression tagRe(QStringLiteral("<[^>]*>"),
341 
342  QString value = getSafeString(input);
343  value.remove(tagRe);
344  return value;
345 }
346 
348  const QVariant &argument,
349  bool autoescape) const
350 {
351  Q_UNUSED(autoescape)
352  QString _input = getSafeString(input);
353  auto width = argument.value<int>();
354  auto partList = _input.split(QLatin1Char(' '), Qt::SkipEmptyParts);
355  if (partList.isEmpty())
356  return QVariant();
357  auto output = partList.takeFirst();
358  auto pos = output.size() - output.lastIndexOf(QLatin1Char('\n')) - 1;
359  Q_FOREACH (const QString &part, partList) {
360  QStringList lines;
361  if (part.contains(QLatin1Char('\n'))) {
362  lines = part.split(QLatin1Char('\n'));
363  } else {
364  lines.append(part);
365  }
366  pos += lines.first().size() + 1;
367  if (pos > width) {
368  output.append(QLatin1Char('\n'));
369  pos += lines.last().size();
370  } else {
371  output.append(QLatin1Char(' '));
372  if (lines.size() > 1)
373  pos += lines.last().size();
374  }
375  output.append(part);
376  }
377  return output;
378 }
379 
381  const QVariant &argument,
382  bool autoescape) const
383 {
384  Q_UNUSED(autoescape)
385  double inputDouble;
386  switch (input.userType()) {
387  case QMetaType::Int:
388  case QMetaType::UInt:
389  case QMetaType::LongLong:
391  case QMetaType::Double:
392  inputDouble = input.toDouble();
393  break;
394  default:
395  inputDouble = getSafeString(input).get().toDouble();
396  }
397 
398  int precision;
399  if (argument.isValid())
400  precision = getSafeString(argument).get().toInt();
401  else
402  precision = 1;
403 
404  return QString::number(inputDouble, 'f', precision);
405 }
406 
408  const QVariant &argument,
409  bool autoescape) const
410 {
411  Q_UNUSED(argument)
412  Q_UNUSED(autoescape)
413  QVariantList list;
414  if (input.userType() == qMetaTypeId<QVariantList>()) {
415  const auto inputList = input.value<QVariantList>();
416  for (const auto &item : inputList) {
417  list << markSafe(getSafeString(item));
418  }
419  }
420  return list;
421 }
422 
424  const QVariant &argument,
425  bool autoescape) const
426 {
427  Q_UNUSED(argument)
428  auto inputString = getSafeString(input);
429  static const QRegularExpression re(QStringLiteral("\n{2,}"));
430  QStringList output;
431 
432  Q_FOREACH (const QString &bit, inputString.get().split(re)) {
433  auto _bit = SafeString(bit, inputString.isSafe());
434  if (autoescape)
435  _bit = conditionalEscape(_bit);
436  _bit.get().replace(QLatin1Char('\n'), QStringLiteral("<br />"));
437  output.append(QStringLiteral("<p>%1</p>").arg(_bit));
438  }
439  return markSafe(output.join(QStringLiteral("\n\n")));
440 }
441 
443  const QVariant &argument,
444  bool autoescape) const
445 {
446  Q_UNUSED(argument)
447  auto inputString = getSafeString(input);
448  if (autoescape && isSafeString(input)) {
449  inputString = conditionalEscape(inputString);
450  }
451  return markSafe(
452  inputString.get().replace(QLatin1Char('\n'), QStringLiteral("<br />")));
453 }
454 
455 static QString nofailStringToAscii(const QString &input)
456 {
457  QString output;
458  output.reserve(input.size());
459 
460  auto it = input.constBegin();
461  const auto end = input.constEnd();
462  static const QChar asciiEndPoint(128);
463  for (; it != end; ++it)
464  if (*it < asciiEndPoint)
465  output.append(*it);
466 
467  return output;
468 }
469 
471  const QVariant &argument,
472  bool autoescape) const
473 {
474  Q_UNUSED(argument)
475  Q_UNUSED(autoescape)
476  QString inputString = getSafeString(input);
477  inputString = inputString.normalized(QString::NormalizationForm_KD);
478  inputString = nofailStringToAscii(inputString);
479  inputString = inputString.trimmed()
480  .toLower()
481  .remove(QRegularExpression(QStringLiteral("[^\\w\\s-]")))
482  .replace(QRegularExpression(QStringLiteral("[-\\s]+")), QStringLiteral("-"));
483  return SafeString(inputString, true);
484 }
485 
487  const QVariant &argument,
488  bool autoescape) const
489 {
490  QVariant ret;
491 
492  Q_UNUSED(autoescape)
493  const auto arg = getSafeString(argument);
494  bool numberConvert = true;
495 
496  qreal size = 0.0f;
497  if (input.canConvert<qreal>()) {
498  size = input.toReal(&numberConvert);
499  if (!numberConvert) {
500  qWarning("%s", "Failed to convert input file size into floating point value.");
501  }
502  } else {
503  size = getSafeString(input).get().toDouble(&numberConvert);
504  if (!numberConvert) {
505  qWarning("%s", "Failed to convert input file size into floating point value.");
506  }
507  }
508 
509  int unitSystem = 10;
510  int precision = 2;
511  qreal multiplier = 1.0f;
512 
513  if (!arg.get().isEmpty()) {
514  const auto argList = arg.get().split(QLatin1Char(','), Qt::SkipEmptyParts);
515  const auto numArgs = argList.size();
516  if (numArgs > 0) {
517  unitSystem = argList.at(0).toInt(&numberConvert);
518  if (!numberConvert) {
519  qWarning("%s", "Failed to convert filse size format unit system into integer. Falling back to default 10.");
520  unitSystem = 10;
521  }
522  }
523 
524  if (numArgs > 1) {
525  precision = argList.at(1).toInt(&numberConvert);
526  if (!numberConvert) {
527  qWarning("%s", "Failed to convert file size format decimal precision into integer. Falling back to default 2.");
528  precision = 2;
529  }
530  }
531 
532  if (numArgs > 2) {
533  multiplier = argList.at(2).toDouble(&numberConvert);
534  if (!numberConvert) {
535  qWarning("%s", "Failed to convert file size format multiplier into double value. Falling back to default 1.0");
536  multiplier = 1.0f;
537  } else {
538  if (multiplier == 0.0f) {
539  qWarning("%s", "It makes no sense to multiply the file size by zero. Using default value 1.0.");
540  multiplier = 1.0f;
541  }
542  }
543  }
544  }
545 
546  const double sizeMult = size * multiplier;
547 
548  if (unitSystem == 10) {
549  if ((sizeMult > -1000) && (sizeMult < 1000)) {
550  precision = 0;
551  }
552  } else if (unitSystem == 2) {
553  if ((sizeMult > - 1024) && (sizeMult < 1024)) {
554  precision = 0;
555  }
556  }
557 
558  const std::pair<qreal,QString> sizePair = calcFileSize(size, unitSystem, multiplier);
559 
560  const QString retString = QString::number(sizePair.first, 'f', precision) + QLatin1Char(' ') + sizePair.second;
561 
562  ret.setValue(retString);
563 
564  return ret;
565 }
566 
567 QVariant TruncateCharsFilter::doFilter(const QVariant &input, const QVariant &argument, bool autoescape) const
568 {
569  Q_UNUSED(autoescape)
570  QString retString = getSafeString(input);
571  int count = getSafeString(argument).get().toInt();
572 
573  if(retString.length() < count) return retString;
574  retString.truncate(count);
575  retString.append(QStringLiteral("..."));
576  return retString;
577 }
578 
579 static QString escapeJson(const QString &input)
580 {
581  QString esc;
582  const int len = input.length();
583  esc.reserve(static_cast<int>(len * 1.2));
584  for (int i = 0; i < len; ++i) {
585  const QChar ch = input.at(i);
586  if (ch == QLatin1Char('>')) {
587  esc += QStringLiteral("\\\\u003E");
588  } else if (ch == QLatin1Char('<')) {
589  esc += QStringLiteral("\\\\u003C");
590  } else if (ch == QLatin1Char('&')) {
591  esc += QStringLiteral("\\\\u0026");
592  } else {
593  esc += ch;
594  }
595  }
596  esc.squeeze();
597  return esc;
598 }
599 
600 QVariant JsonScriptFilter::doFilter(const QVariant &input, const QVariant &argument, bool autoescape) const
601 {
602  Q_UNUSED(autoescape)
603  if (input.isNull() || !input.isValid()) {
604  return QVariant();
605  }
606 
607  const QString arg = escape(getSafeString(argument));
608 
609  QJsonDocument json;
610  if (input.canConvert<QJsonDocument>()) {
611  json = input.toJsonDocument();
612  } else if (input.canConvert<QJsonObject>()) {
613  json.setObject(input.toJsonObject());
614  } else if (input.canConvert<QJsonArray>()) {
615  json.setArray(input.toJsonArray());
616  } else {
617  qWarning("%s", "Can not convert input data into QJsonObject or QJSonArray.");
618  return QVariant();
619  }
620 
622  jsonString = escapeJson(jsonString);
623 
624  const QString scriptString = u"<script id=\"" + arg + u"\" type=\"application/json\">" + jsonString + u"</script>";
625 
626  return SafeString(scriptString, true);
627 }
const_iterator constBegin() const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QString & append(QChar ch)
QVariant doFilter(const QVariant &input, const QVariant &argument=QVariant(), bool autoescape={}) const override
QString toUpper() const const
void truncate(qsizetype position)
QByteArray toJson(JsonFormat format) const const
QJsonDocument toJsonDocument() const const
iterator end()
Cutelee::SafeString markSafe(const Cutelee::SafeString &input)
Definition: util.cpp:93
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
SafeString escape(const QString &input) const
Definition: filter.cpp:10
void setArray(const QJsonArray &array)
qsizetype size() const const
T value() const const
char32_t toUpper(char32_t ucs4)
QString join(QChar separator) const const
QString fromUtf8(QByteArrayView str)
double toDouble(bool *ok) const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
qsizetype size() const const
bool isSafeString(const QVariant &input)
Definition: util.cpp:120
QString normalized(NormalizationForm mode, QChar::UnicodeVersion version) const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
SafeString conditionalEscape(const SafeString &input) const
Definition: filter.cpp:22
Cutelee::SafeString markForEscaping(const Cutelee::SafeString &input)
Definition: util.cpp:101
const_iterator constEnd() const const
QString number(double n, char format, int precision)
bool canConvert() const const
QJsonObject toJsonObject() const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
bool isNull() const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QString rightJustified(qsizetype width, QChar fill, bool truncate) const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QChar fromLatin1(char c)
int toInt(bool *ok, int base) const const
QString trimmed() const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
T & first()
Utility functions used throughout Cutelee.
A QString wrapper class for containing whether a string is safe or needs to be escaped.
Definition: safestring.h:91
int userType() const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QString toLower() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
SkipEmptyParts
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
void append(QList< T > &&value)
const QChar at(qsizetype position) const const
T & last()
QList< T > mid(qsizetype pos, qsizetype length) const const
qsizetype length() const const
QJsonArray toJsonArray() const const
void reserve(qsizetype size)
QString leftJustified(qsizetype width, QChar fill, bool truncate) const const
QVariant doFilter(const QVariant &input, const QVariant &argument=QVariant(), bool autoescape={}) const override
NormalizationForm_KD
void setObject(const QJsonObject &object)
bool isValid() const const
double toDouble(bool *ok) const const
std::pair< qreal, QString > calcFileSize(qreal size, int unitSystem=10, qreal multiplier=1.0)
Definition: util.cpp:196
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
qreal toReal(bool *ok) const const
iterator begin()
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
bool isSafe() const override
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
QString toString() const const
QVariant doFilter(const QVariant &input, const QVariant &argument=QVariant(), bool autoescape={}) const override
void squeeze()
const NestedString & get() const
Definition: safestring.h:325
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Cutelee::SafeString getSafeString(const QVariant &input)
Definition: util.cpp:111
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
void setValue(QVariant &&value)