
Les bons livres de programmation disent que le code doit être auto-documenté. Et des commentaires sont nécessaires là où quelque chose de non trivial est fait. Notre équipe partage cette opinion et nous sommes récemment tombés sur un morceau de code qui le démontre parfaitement.
Le code que nous examinerons ensuite a été rédigé au cours du travail sur l'article "La gestion des dates attire des erreurs ou 77 défauts dans Qt 6 ".
L'analyseur PVS-Studio a attiré l'attention sur ce fragment de code, émettant un avertissement: V575 [CWE-628] La fonction 'memcpy' ne copie pas la chaîne entière. Utilisez la fonction 'strcpy / strcpy_s' pour conserver la valeur null du terminal. qplaintestlogger.cpp 253. En fait, le voici:
const char *msgFiller = msg[0] ? " " : "";
QTestCharBuffer testIdentifier;
QTestPrivate::generateTestIdentifier(&testIdentifier);
QTest::qt_asprintf(&messagePrefix, "%s: %s%s%s%s\n",
type, testIdentifier.data(), msgFiller, msg,
failureLocation.data());
// In colored mode, printf above stripped our nonprintable control characters.
// Put them back.
memcpy(messagePrefix.data(), type, strlen(type));
outputMessage(messagePrefix.data());
Notez l'appel à la fonction memcpy . À lui seul, ce code soulève deux questions à la fois:
- Pourquoi quelque chose est-il écrit dans un tampon dont le contenu vient d'être généré à l'aide d'une fonction de type printf?
- Certainement pas une erreur que le terminal zéro n'est pas copié? C'est exactement ce que l'analyseur n'aime pas.
, . .
. , . .
:
char buf[1024];
if (result.setByMacro) {
qsnprintf(buf, sizeof(buf), "%s%s%s%s%s%s\n", buf1, bufTag, fill,
buf2, buf2_, buf3);
} else {
qsnprintf(buf, sizeof(buf), "%s%s%s%s\n", buf1, bufTag, fill, buf2);
}
memcpy(buf, bmtag, strlen(bmtag));
outputMessage(buf);
. . , . , memcpy. , , buf1, bmtag. , . .
, : Andrey Karpov. One Useful Comment.