You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Qt中验证XML输入值:寻求规避代码注入的更简便方案

更简便的QLineEdit输入验证方法(避免XML危险字符)

我希望避免代码注入,因此子类化了QValidator,用于检查QLineEdit中的字符串是否不包含<、>、&、"、'等“危险”字符。请问是否有更简便的方法来验证给定字符串的输入?感谢您的建议。相关代码片段如下:

myvalidator.h

extern class cXMLValueValidator : public QValidator{
    Q_OBJECT
public:
    explicit cXMLValueValidator(QObject *parent = 0);
    virtual State validate(QString &input, int &pos) const;
};

myvalidator.cpp

QValidator::State cXMLValueValidator::validate(QString &input, int &pos) const {
    // 原检查危险字符的实现逻辑
}

更简便的替代方案

嘿,这个需求其实不用自己从零写Validator,Qt本身就有不少现成的工具可以帮你简化,给你几个实用的思路:

1. 直接用QRegularExpressionValidator限制合法字符

最省事的方法是定义一个只允许安全字符的正则表达式,然后用Qt自带的QRegularExpressionValidator绑定到QLineEdit上,它会自动帮你拦截非法输入:

// 示例规则:允许字母、数字、空格、中文,以及!@#$%^&*()_+-=,.?/\\这类安全符号,排除<>&"'
QRegularExpression safeRegex(R"([a-zA-Z0-9\s\u4e00-\u9fa5!@#$%^&*()_+\-=,.?/\\]+)");
auto validator = new QRegularExpressionValidator(safeRegex, yourLineEdit);
yourLineEdit->setValidator(validator);

这样用户输入危险字符时,QLineEdit会直接阻止输入,或者在调用hasAcceptableInput()时返回false,完全不用自己写validate的逻辑。

2. 用XML转义工具做“安全处理”而非“拦截”

如果你只是担心XML注入问题,其实也可以换个思路:不阻止用户输入这些字符,而是在获取输入后用Qt的转义工具把危险字符转换成XML安全实体。比如Qt5+可以用QString::toHtmlEscaped()

QString userInput = yourLineEdit->text();
QString safeXmlValue = userInput.toHtmlEscaped();
// 之后用safeXmlValue去生成XML内容即可,<会变成&lt;,>变成&gt;,以此类推

这种方法适合需要允许用户输入任意内容,但要保证XML输出安全的场景。

3. 简化自定义Validator的实现

如果还是想保留自定义Validator的方式,也可以大幅简化validate函数的逻辑,不用逐个字符遍历检查,直接用QString::contains()批量判断:

QValidator::State cXMLValueValidator::validate(QString &input, int &pos) const {
    // 检查是否包含任何危险字符
    if (input.contains(QRegularExpression(R"([<>&"'])"))) {
        return Invalid;
    }
    return Acceptable;
}

或者用字符数组遍历的简化写法:

QValidator::State cXMLValueValidator::validate(QString &input, int &pos) const {
    const QChar dangerChars[] = {'<', '>', '&', '"', '\''};
    for (const QChar c : dangerChars) {
        if (input.contains(c)) {
            return Invalid;
        }
    }
    return Acceptable;
}

这样比原有的逐个字符判断代码简洁太多,可读性也更好。


内容的提问来源于stack exchange,提问作者Armin the Crossman

火山引擎 最新活动