Nous utilisons des cookies pour améliorer votre expérience de navigation. En savoir plus
Accepter
to the top
close form

Remplissez le formulaire ci‑dessous en 2 étapes simples :

Vos coordonnées :

Étape 1
Félicitations ! Voici votre code promo !

Type de licence souhaité :

Étape 2
Team license
Enterprise licence
** En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité
close form
Demandez des tarifs
Nouvelle licence
Renouvellement de licence
--Sélectionnez la devise--
USD
EUR
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
La licence PVS‑Studio gratuit pour les spécialistes Microsoft MVP
close form
Pour obtenir la licence de votre projet open source, s’il vous plait rempliez ce formulaire
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
I am interested to try it on the platforms:
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
check circle
Votre message a été envoyé.

Nous vous répondrons à


Si vous n'avez toujours pas reçu de réponse, vérifiez votre dossier
Spam/Junk et cliquez sur le bouton "Not Spam".
De cette façon, vous ne manquerez la réponse de notre équipe.

>
>
>
V111. Call of function 'foo' with varia…
menu mobile close menu
Analyzer diagnostics
General Analysis (C++)
General Analysis (C#)
General Analysis (Java)
Micro-Optimizations (C++)
Diagnosis of 64-bit errors (Viva64, C++)
Customer specific requests (C++)
MISRA errors
AUTOSAR errors
OWASP errors (C#)
Problems related to code analyzer
Additional information
toggle menu Contents

V111. Call of function 'foo' with variable number of arguments. N argument has memsize type.

15 Déc 2011

The analyzer found a possible error related to the transfer of the actual argument of memsize type into the function with variable number of arguments. The possible error may consist in the change of demands made to the function on the 64-bit system.

Let's examine an example.

const char *invalidFormat = "%u";
size_t value = SIZE_MAX;
printf(invalidFormat, value);

The given code does not take into account that 'size_t' type does not coincide with 'unsigned' type on the 64-bit platform. It will cause the printing of the incorrect result in case if "value > UINT_MAX". The analyzer warns you that memsize type is used as an actual argument. It means that you should check the line 'invalidFormat' assigning the printing format. The correct variant may look as follows:

const char *validFormat = "%Iu";
size_t value = SIZE_MAX;
printf(validFormat, value);

In the code of a real application, this error can occur in the following form, e.g.:

wsprintf(szDebugMessage,
          _T("%s location %08x caused an access violation.\r\n"),
         readwrite,
         Exception->m_pAddr);

The second example.

char buf[9];
sprintf(buf, "%p", pointer);

The author of this inaccurate code did not take into account that the pointer size may excess 32 bits later. As a result, this code will cause buffer overflow on the 64-bit architecture. After checking the code on which the V111 warning message is shown you may choose one of the two ways: to increase the buffer size or rewrite the code using safe constructions.

char buf[sizeof(pointer) * 2 + 1];
sprintf(buf, "%p", pointer);
// --- or ---
std::stringstream s;
s << pointer;

The third example.

char buf[9];
sprintf_s(buf, sizeof(buf), "%p", pointer);

While examining the second example you could rightly notice that in order to prevent the overflow you should use functions with security enhancements. In this case the buffer overflow won't occur but unfortunately the correct result won't be shown as well.

If the arguments types did not change their digit capacity the code is considered to be correct and warning messages won't be shown. The example:

printf("%d", 10*5);
CString str;
size_t n = sizeof(float);
str.Format(StrFormat, static_cast<int>(n));

Unfortunately, we often cannot distinguish the correct code from the incorrect one while diagnosing the described type of errors. This warning message will be shown on many of calls of the functions with variable items number even when the call is absolutely correct. It is related to the principal danger of using such C++ constructions. Most frequent problems are the problems with the use of variants of the following functions: 'printf', 'scanf', 'CString::Format'. The generally accepted practice is to refuse them and to use safe programming methods. For example, you may replace 'printf' with 'cout' and 'sprintf' with 'boost::format' or 'std::stringstream'.

Note. Eliminating false positives when working with formatted output functions

The V111 diagnostic is very simple. When the analyzer has no information about a variadic function, it warns you about every case when variable of memsize-type is passed to that function. When it does have the information, the more accurate diagnostic V576 joins in and V111 diagnostic will not issue a warning. When V576 is disabled, V111 will work in any case.

Therefore, you can reduce the number of false positives by providing the analyzer with information about the format functions. The analyzer is already familiar with such typical functions as 'printf', 'sprintf', etc., so it is user-implemented functions that you want to annotate. See the description of the V576 diagnostic for details about annotating functions.

Consider the following example. You may ask, "Why does not the analyzer output a V111 warning in case N1, but does that in case N2?"

void OurLoggerFn(wchar_t const* const _Format, ...)
{
  ....
}
void Foo(size_t length)
{
  wprintf( L"%Iu", length );     // N1
  OurLoggerFn( L"%Iu", length ); // N2
}

The reason is that the analyzer knows how standard function 'wprintf' works, while it knows nothing about 'OurLoggerFn', so it prefers to be overcautious and issues a warning about passing a memsize-type variable ('size_t' in this case) as an actual argument to a variadic function.

To eliminate the V111 warning, annotate the 'OurLoggerFn' function as follows:

//+V576, function:OurLoggerFn, format_arg:1, ellipsis_arg:2
void OurLoggerFn(wchar_t const* const _Format, ...)
.....

Additional materials on this topic: