lundi 7 décembre 2015

How to detect snprintf failure?

I am using snprintf to format string using user-defined format (also given as string). The code looks like this:

void DataPoint::valueReceived( QVariant value ) {
    // Get the formating QVariant, which is only considered valid if it's string
    QVariant format = this->property("format");
    if( format.isValid() && format.type()==QMetaType::QString && !format.isNull() ) {
        // Convert QString to std string
        const std::string formatStr = format.toString().toStdString();
        LOGMTRTTIINFO(pointName<<"="<<value.toString().toUtf8().constData()<<"=>"<<formatStr<<"["<<formatStr.length()<<'\n');
        // The attempt to catch exceptions caused by invalid formating string
        try {
            if( value.type() == QMetaType::QString ) {
                // Treat value as string (values are allways ASCII)
                const std::string array = value.toString().toStdString();
                const char* data = (char*)array.c_str();
                // Assume no more than 10 characters are added during formating.
                char* result = (char*)calloc(array.length()+10, sizeof(char));
                snprintf(result, array.length()+10, formatStr.c_str(), data);
                value = result;
            }
            // If not string, then it's a number.
            else {
                double data = value.toDouble();
                char* result = (char*)calloc(30, sizeof(char));
                // Even 15 characters is already longer than largest number you can make any sense of
                snprintf(result, 30, formatStr.c_str(), data);
                LOGMTRTTIINFO(pointName<<"="<<data<<"=>"<<formatStr<<"["<<formatStr.length()<<"]=>"<<result<<'\n');
                value = result;
            }
        } catch(...) {
            LOGMTRTTIERR("Format error in "<<pointName<<'\n');
        }
    }
    ui->value->setText(value.toString());
}

As you can see I assumed there will be some exception. But there's not, invalid formatting string results in gibberish. This is what I get if I try to format double using %s:

image description

So is there a way to detect that invalid formatting option was selected, such as formatting number as string or vice-versa? And what if totally invalid formatting string is given?

Aucun commentaire:

Enregistrer un commentaire