Warum PVS-Studio die Datenflussanalyse verwendet: Aufgrund eines interessanten Fehlers in der Open Asset Import Library

PVS-Studio - Datenflussanalyse

Die Datenflussanalyse ist ein wesentlicher Bestandteil jedes modernen statischen Code-Analysators. Von außen ist jedoch nicht klar, was dies ist und was am wichtigsten ist - warum es benötigt wird. Bisher assoziieren einige Leute statische Analysen mit der Suche nach etwas im Code nach einem bestimmten Muster. Daher schreiben wir von Zeit zu Zeit Notizen, in denen wir zeigen, wie diese oder jene Technologie, die im PVS-Studio-Analysegerät verwendet wird, dazu beiträgt, einen weiteren interessanten Fehler aufzudecken. Heute ist genau ein solcher Artikel, in dem wir einen Fehler in einer der Implementierungen des Base64-Binärdatencodierungsstandards betrachten werden.







Alles begann mit der Überprüfung der neuesten Version der Qt 6-Bibliothek. Dies war ein separater klassischer Artikel , in dem ich 77 gefundene Fehler beschrieb. So kam es, dass ich mich zunächst entschied, den Bericht zu überfliegen, ohne die Warnungen in Bezug auf Bibliotheken von Drittanbietern zu verbergen. Mit anderen Worten, ich habe Warnungen in Bezug auf \ src \ 3rdparty in den Einstellungen nicht deaktiviert. Und so kam es, dass ich sofort auf ein interessantes Beispiel für einen Fehler in der Open Asset Import Library stieß , über den ich mich entschied, diese separate kleine Notiz zu machen.







, , PVS-Studio, . . , , ", PVS-Studio ".







, , , Open Asset Import Library (assimp). : \src\3rdparty\assimp\src\code\FBX\FBXUtil.cpp.







std::string EncodeBase64(const char* data, size_t length)
{
    // calculate extra bytes needed to get a multiple of 3
    size_t extraBytes = 3 - length % 3;

    // number of base64 bytes
    size_t encodedBytes = 4 * (length + extraBytes) / 3;

    std::string encoded_string(encodedBytes, '=');

    // read blocks of 3 bytes
    for (size_t ib3 = 0; ib3 < length / 3; ib3++)
    {
        const size_t iByte = ib3 * 3;
        const size_t iEncodedByte = ib3 * 4;
        const char* currData = &data[iByte];

        EncodeByteBlock(currData, encoded_string, iEncodedByte);
    }

    // if size of data is not a multiple of 3,
    // also encode the final bytes (and add zeros where needed)
    if (extraBytes > 0)
    {
        char finalBytes[4] = { 0,0,0,0 };
        memcpy(&finalBytes[0], &data[length - length % 3], length % 3);

        const size_t iEncodedByte = encodedBytes - 4;
        EncodeByteBlock(&finalBytes[0], encoded_string, iEncodedByte);

        // add '=' at the end
        for (size_t i = 0; i < 4 * extraBytes / 3; i++)
            encoded_string[encodedBytes - i - 1] = '=';
    }
    return encoded_string;
}
      
      





, . , , Base64 :). :







  1. 31 ;
  2. ;
  3. legacy .


Ok, . Base64. 64 . - A-Z, a-z 0-9 (62 ) 2 , . 3 4 .







, , "=". . .







, . , . , , - . "- " : V547 [CWE-571] Expression 'extraBytes > 0' is always true. FBXUtil.cpp 224







, , extraBytes:







// calculate extra bytes needed to get a multiple of 3
size_t extraBytes = 3 - length % 3;
      
      





, , 3. 3. :







size_t extraBytes = length % 3;
      
      





, , , 5 , 5 % 3 = 2, 2 . 6 , , 6 % 3 = 0.







, , . :







size_t extraBytes = (3 - length % 3) % 3;
      
      





, . , :







size_t extraBytes = 3 - length % 3;
      
      





. length, [0..2]. PVS-Studio , . . . Value Range Analysis. .







:







size_t extraBytes = 3 - [0..2];
      
      





, extraBytes . : [1..3].







, . , , , :







if (extraBytes > 0)
      
      





, , , , , , , .







, , , . . , 6 . 8 . , .







// calculate extra bytes needed to get a multiple of 3
size_t extraBytes = 3 - length % 3; // 3-6%3 = 3

// number of base64 bytes
size_t encodedBytes = 4 * (length + extraBytes) / 3; // 4*(6+3)/3 = 12

std::string encoded_string(encodedBytes, '=');
      
      





, 12 , 8. – .







. , - , , Base64. , , , " , ".







PVS-Studio , . :). , . .







, : Andrey Karpov. Why PVS-Studio Uses Data Flow Analysis: Based on Gripping Error in Open Asset Import Library.








All Articles