Unicorn with delicious cookie
Nous utilisons des cookies pour améliorer votre expérience de navigation. En savoir plus
Accepter
to the top
>
>
>
How PVS-Studio prevents rash code chang…

How PVS-Studio prevents rash code changes, example N3

16 Fév 2022
Author:

Let's continue with a series of small notes illustrating the PVS-Studio's ability to quickly find new errors in the code. If the analyzer is regularly used, of course :). Today we have another bug in the Blender project.

I monitor the Blender project for fun. Every day I get a PVS-Studio report with warnings related to the new code. Sometimes an error catches my attention and I write a note about it. That's what I'm doing right now :).

I won't give you links to the previous articles, since they are of the same type. With these articles I want to show you that regular use of the static analyzer helps quickly find errors. The earlier the error is found, the lower the cost of fixing it.

This time my attention was caught by two PVS-Studio warnings. The analyzer was triggered by one code line:

  • [CWE-480] V616: The 'OB_MODE_OBJECT' named constant with the value of 0 is used in the bitwise operation. transform_snap_object.c 480
  • [CWE-571] V560: A part of conditional expression is always true: !(base->object->mode & OB_MODE_OBJECT). transform_snap_object.c 480

This is OK. One code bug can be suspicious for several diagnostic rules. We have just the case here:

if (is_object_active && !(base->object->mode & OB_MODE_OBJECT)) {

If you've read the analyzer warnings, you already know what's going on. However, if you look at the code without these warnings, it seems completely normal. This code line can go unnoticed during code review.

To understand that the code is incorrect, you need to look at how the named constant is declared in the eObjectMode enumeration:

typedef enum eObjectMode {
  OB_MODE_OBJECT = 0,
  OB_MODE_EDIT = 1 << 0,
  OB_MODE_SCULPT = 1 << 1,
  OB_MODE_VERTEX_PAINT = 1 << 2,
  OB_MODE_WEIGHT_PAINT = 1 << 3,
  OB_MODE_TEXTURE_PAINT = 1 << 4,
  OB_MODE_PARTICLE_EDIT = 1 << 5,
  OB_MODE_POSE = 1 << 6,
  OB_MODE_EDIT_GPENCIL = 1 << 7,
  OB_MODE_PAINT_GPENCIL = 1 << 8,
  OB_MODE_SCULPT_GPENCIL = 1 << 9,
  OB_MODE_WEIGHT_GPENCIL = 1 << 10,
  OB_MODE_VERTEX_GPENCIL = 1 << 11,
} eObjectMode;

The OB_MODE_OBJECT constant is zero! Let's look at the condition once again:

if (is_object_active && !(base->object->mode & OB_MODE_OBJECT)) {

Thus, the result of the bitwise AND (&) operation is always zero. The first analyzer's message warns us about this.

If we apply the "!" operator to 0, we get the following expression:

if (is_object_active && true) {

The second analyzer message tells us that the part of the expression is always true.

Most likely, the correct option would look like this:

if (is_object_active && base->object->mode != OB_MODE_OBJECT) {

I'm not sure though, I don't understand the Blender's source code well. The analyzer's task is to point out an error. It's up to the developer to decide what to do with it.

Hope you enjoyed this note. Subscribe to my Twitter: @Code_Analysis.

Additional links:

Popular related articles

S'abonner

Comments (0)

close comment form
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 want to join the test
* 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 l'e-mail n'apparaît pas dans votre boîte de réception, recherchez-le dans l'un des dossiers suivants:

  • Promotion
  • Notifications
  • Spam