21#include "stringfilters.h"
25#include <QtCore/QRegularExpression>
26#include <QtCore/QVariant>
30 bool autoescape)
const
36 .replace(QLatin1Char(
'\\'), QStringLiteral(
"\\\\"))
38 .replace(QLatin1Char(
'\"'), QStringLiteral(
"\\\""))
40 .replace(QLatin1Char(
'\''), QStringLiteral(
"\\\'"));
46 bool autoescape)
const
51 if (safeString.get().isEmpty())
54 return QVariant(safeString.get().at(0).toUpper()
56 safeString.get().right(safeString.get().size() - 1)));
59EscapeJsFilter::EscapeJsFilter() {}
61static QList<std::pair<QString, QString>> getJsEscapes()
63 QList<std::pair<QString, QString>> jsEscapes;
64 jsEscapes << std::pair<QString, QString>(QChar::fromLatin1(
'\\'),
65 QStringLiteral(
"\\u005C"))
66 << std::pair<QString, QString>(QChar::fromLatin1(
'\''),
67 QStringLiteral(
"\\u0027"))
68 << std::pair<QString, QString>(QChar::fromLatin1(
'\"'),
69 QStringLiteral(
"\\u0022"))
70 << std::pair<QString, QString>(QChar::fromLatin1(
'>'),
71 QStringLiteral(
"\\u003E"))
72 << std::pair<QString, QString>(QChar::fromLatin1(
'<'),
73 QStringLiteral(
"\\u003C"))
74 << std::pair<QString, QString>(QChar::fromLatin1(
'&'),
75 QStringLiteral(
"\\u0026"))
76 << std::pair<QString, QString>(QChar::fromLatin1(
'='),
77 QStringLiteral(
"\\u003D"))
78 << std::pair<QString, QString>(QChar::fromLatin1(
'-'),
79 QStringLiteral(
"\\u002D"))
80 << std::pair<QString, QString>(QChar::fromLatin1(
';'),
81 QStringLiteral(
"\\u003B"))
82 << std::pair<QString, QString>(QChar(0x2028), QStringLiteral(
"\\u2028"))
83 << std::pair<QString, QString>(QChar(0x2029),
84 QStringLiteral(
"\\u2029"));
86 for (
auto i = 0; i < 32; ++i) {
87 jsEscapes << std::pair<QString, QString>(
89 QStringLiteral(
"\\u00")
90 + QStringLiteral(
"%1").arg(i, 2, 16, QLatin1Char(
'0')).toUpper());
97 bool autoescape)
const
103 static const auto jsEscapes = getJsEscapes();
105 for (
auto &
escape : jsEscapes) {
106 retString = retString.replace(
escape.first,
escape.second);
113 bool autoescape)
const
119 const QRegularExpression fixAmpersandsRegexp(
120 QStringLiteral(
"&(?!(\\w+|#\\d+);)"));
122 safeString.get().replace(fixAmpersandsRegexp, QStringLiteral(
"&"));
128 bool autoescape)
const
134 auto inputSafe = retString.isSafe();
136 retString.get().remove(argString);
138 if (inputSafe && argString.get() != QChar::fromLatin1(
';'))
145 bool autoescape)
const
154 bool autoescape)
const
158 auto lines = safeString.get().split(QLatin1Char(
'\n'));
159 auto width = QString::number(lines.size()).size();
161 const auto shouldEscape = (autoescape && !safeString.isSafe());
162 for (
auto i = 0; i < lines.size(); ++i) {
164 = QStringLiteral(
"%1. %2")
166 .arg(shouldEscape ?
QString(
escape(lines.at(i))) : lines.at(i));
169 return SafeString(lines.join(QChar::fromLatin1(
'\n')),
true);
173 bool autoescape)
const
182 bool autoescape)
const
188 else if (input.userType() == qMetaTypeId<QVariantList>()) {
189 a = toString(input.value<QVariantList>());
197 bool autoescape)
const
204 auto it = str.begin();
205 const auto end = str.end();
208 for (; it != end; ++it) {
213 toUpper = it->isSpace();
221 bool autoescape)
const
227 auto numWords = s.get().toInt(&ok);
230 return input.toString();
234#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
235 auto words = inputString.split(QLatin1Char(
' '), QString::SkipEmptyParts);
237 auto words = inputString.split(QLatin1Char(
' '), Qt::SkipEmptyParts);
240 if (words.size() > numWords) {
241 words = words.mid(0, numWords);
242 if (!words.at(words.size() - 1).endsWith(QStringLiteral(
"..."))) {
243 words << QStringLiteral(
"...");
246 return words.join(QChar::fromLatin1(
' '));
250 bool autoescape)
const
259 bool autoescape)
const
263 return QString::number(
268 bool autoescape)
const
276 bool autoescape)
const
284 bool autoescape)
const
288 const auto valueWidth = value.size();
290 const auto totalPadding = width - valueWidth;
291 const auto rightPadding = totalPadding >> 1;
293 return value.leftJustified(valueWidth + rightPadding).rightJustified(width);
297 bool autoescape)
const
306 bool autoescape)
const
315 bool autoescape)
const
320 = QStringLiteral(
"(%1)").arg(tags.join(QChar::fromLatin1(
'|')));
321 const QRegularExpression startTag(
322 QStringLiteral(
"<%1(/?>|(\\s+[^>]*>))").arg(tagRe));
323 const QRegularExpression endTag(QStringLiteral(
"</%1>").arg(tagRe));
326 const auto safeInput = value.isSafe();
327 value.get().remove(startTag);
328 value.get().remove(endTag);
336 bool autoescape)
const
340 static QRegularExpression tagRe(QStringLiteral(
"<[^>]*>"),
341 QRegularExpression::InvertedGreedinessOption);
350 bool autoescape)
const
354 auto width = argument.value<
int>();
355#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
356 auto partList = _input.split(QLatin1Char(
' '), QString::SkipEmptyParts);
358 auto partList = _input.split(QLatin1Char(
' '), Qt::SkipEmptyParts);
360 if (partList.isEmpty())
362 auto output = partList.takeFirst();
363 auto pos = output.size() - output.lastIndexOf(QLatin1Char(
'\n')) - 1;
364 Q_FOREACH (
const QString &part, partList) {
366 if (part.contains(QLatin1Char(
'\n'))) {
367 lines = part.split(QLatin1Char(
'\n'));
371 pos += lines.first().size() + 1;
373 output.append(QLatin1Char(
'\n'));
374 pos += lines.last().size();
376 output.append(QLatin1Char(
' '));
377 if (lines.size() > 1)
378 pos += lines.last().size();
387 bool autoescape)
const
391 switch (input.userType()) {
393 case QMetaType::UInt:
394 case QMetaType::LongLong:
395 case QMetaType::ULongLong:
396 case QMetaType::Double:
397 inputDouble = input.toDouble();
404 if (argument.isValid())
409 return QString::number(inputDouble,
'f', precision);
414 bool autoescape)
const
419 if (input.userType() == qMetaTypeId<QVariantList>()) {
420 const auto inputList = input.value<QVariantList>();
421 for (
const auto &item : inputList) {
430 bool autoescape)
const
434 static const QRegularExpression re(QStringLiteral(
"\n{2,}"));
437 Q_FOREACH (
const QString &bit, inputString.get().split(re)) {
438 auto _bit =
SafeString(bit, inputString.isSafe());
441 _bit.get().replace(QLatin1Char(
'\n'), QStringLiteral(
"<br />"));
442 output.append(QStringLiteral(
"<p>%1</p>").arg(_bit));
444 return markSafe(output.join(QStringLiteral(
"\n\n")));
449 bool autoescape)
const
457 inputString.get().replace(QLatin1Char(
'\n'), QStringLiteral(
"<br />")));
463 output.reserve(input.size());
465 auto it = input.constBegin();
466 const auto end = input.constEnd();
467 static const QChar asciiEndPoint(128);
468 for (; it != end; ++it)
469 if (*it < asciiEndPoint)
477 bool autoescape)
const
482 inputString = inputString.normalized(QString::NormalizationForm_KD);
483 inputString = nofailStringToAscii(inputString);
484 inputString = inputString.trimmed()
486 .remove(QRegularExpression(QStringLiteral(
"[^\\w\\s-]")))
487 .replace(QRegularExpression(QStringLiteral(
"[-\\s]+")), QStringLiteral(
"-"));
493 bool autoescape)
const
499 bool numberConvert =
true;
502 if (input.canConvert<qreal>()) {
503 size = input.toReal(&numberConvert);
504 if (!numberConvert) {
505 qWarning(
"%s",
"Failed to convert input file size into floating point value.");
509 if (!numberConvert) {
510 qWarning(
"%s",
"Failed to convert input file size into floating point value.");
516 qreal multiplier = 1.0f;
518 if (!arg.get().isEmpty()) {
519#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
520 const auto argList = arg.get().split(QLatin1Char(
','), QString::SkipEmptyParts);
522 const auto argList = arg.get().split(QLatin1Char(
','), Qt::SkipEmptyParts);
524 const auto numArgs = argList.size();
526 unitSystem = argList.at(0).toInt(&numberConvert);
527 if (!numberConvert) {
528 qWarning(
"%s",
"Failed to convert filse size format unit system into integer. Falling back to default 10.");
534 precision = argList.at(1).toInt(&numberConvert);
535 if (!numberConvert) {
536 qWarning(
"%s",
"Failed to convert file size format decimal precision into integer. Falling back to default 2.");
542 multiplier = argList.at(2).toDouble(&numberConvert);
543 if (!numberConvert) {
544 qWarning(
"%s",
"Failed to convert file size format multiplier into double value. Falling back to default 1.0");
547 if (multiplier == 0.0f) {
548 qWarning(
"%s",
"It makes no sense to multiply the file size by zero. Using default value 1.0.");
555 const double sizeMult = size * multiplier;
557 if (unitSystem == 10) {
558 if ((sizeMult > -1000) && (sizeMult < 1000)) {
561 }
else if (unitSystem == 2) {
562 if ((sizeMult > - 1024) && (sizeMult < 1024)) {
567 const std::pair<qreal,QString> sizePair =
calcFileSize(size, unitSystem, multiplier);
569 const QString retString = QString::number(sizePair.first,
'f', precision) + QLatin1Char(
' ') + sizePair.second;
571 ret.setValue(retString);
582 if(retString.length() < count)
return retString;
583 retString.truncate(count);
584 retString.append(QStringLiteral(
"..."));
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 escape(const QString &input) const
SafeString conditionalEscape(const SafeString &input) const
A QString wrapper class for containing whether a string is safe or needs to be escaped.
const NestedString & get() 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
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
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
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=QVariant(), 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
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
std::pair< qreal, QString > calcFileSize(qreal size, int unitSystem=10, qreal multiplier=1.0)
bool isSafeString(const QVariant &input)
Cutelee::SafeString getSafeString(const QVariant &input)
Cutelee::SafeString markSafe(const Cutelee::SafeString &input)
Cutelee::SafeString markForEscaping(const Cutelee::SafeString &input)
Utility functions used throughout Cutelee.