Our website uses cookies to enhance your browsing experience.
Accept
to the top
close form

Fill out the form in 2 simple steps below:

Your contact information:

Step 1
Congratulations! This is your promo code!

Desired license type:

Step 2
Team license
Enterprise license
** By clicking this button you agree to our Privacy Policy statement
close form
Request our prices
New License
License Renewal
--Select currency--
USD
EUR
* By clicking this button you agree to our Privacy Policy statement

close form
Free PVS‑Studio license for Microsoft MVP specialists
* By clicking this button you agree to our Privacy Policy statement

close form
To get the licence for your open-source project, please fill out this form
* By clicking this button you agree to our Privacy Policy statement

close form
I am interested to try it on the platforms:
* By clicking this button you agree to our Privacy Policy statement

close form
check circle
Message submitted.

Your message has been sent. We will email you at


If you do not see the email in your inbox, please check if it is filtered to one of the following folders:

  • Promotion
  • Updates
  • Spam

Webinar: C++ semantics - 06.11

>
>
>
Examples of errors detected by the V781…

Examples of errors detected by the V781 diagnostic

V781. Value of a variable is checked after it is used. Possible error in program's logic. Check lines: N1, N2.


FreeBSD Kernel

V781 The value of the 'lun' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 1617, 1619. sbp_targ.c 1617


static void
sbp_targ_mgm_handler(struct fw_xfer *xfer)
{
  ....
  int exclusive = 0, lun;
  ....
  lun = orb4->id;
  lstate = orbi->sc->lstate[lun];

  if (lun >= MAX_LUN || lstate == NULL ||
      (exclusive &&
      STAILQ_FIRST(&lstate->logins) != NULL &&
      STAILQ_FIRST(&lstate->logins)->fwdev != orbi->fwdev)
     ) {
    /* error */
    orbi->status.dead = 1;
    orbi->status.status = STATUS_ACCESS_DENY;
    orbi->status.len = 1;
    break;
  }
  ....
}

XNU kernel

V781 CWE-129 The value of the 'channel_index' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 852, 855. IOStateReporter.cpp 852


IOReturn
IOStateReporter::updateChannelValues(int channel_index)
{
  ....
  state_index = _currentStates[channel_index];

  if (channel_index < 0 ||
      channel_index > (_nElements - state_index)
                        / _channelDimension) {
    result = kIOReturnOverrun; goto finish;
  }
  ....
}

It is very suspicious that the variable channel_index is used as an array index. And only after that a check occurs, that the variable does not exceed certain limits values.

Similar errors can be found in some other places:

  • V781 CWE-129 The value of the 'channel_index' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 651, 654. IOStateReporter.cpp 651
  • V781 CWE-129 The value of the 'pri' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 267, 269. pktsched_fq_codel.c 267
  • V781 CWE-129 The value of the 'pcid' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 224, 225. pmap_pcid.c 224

System Shock

V781 The value of the 'num_args' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 224, 225. FIX24TST.C 224


#define MAX_ARGS 8
....
bool args_neg[MAX_ARGS];
....
void parse (char *str, bool command)
{
  ....
  args_neg[num_args] = neg = FALSE;
  if (num_args == MAX_ARGS) break;
  ....
}

System Shock

V781 The value of the 'model_num' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 567, 569. RENDTOOL.C 567


uchar model_base_nums[MAX_VTEXT_OBJS];
....
void load_model_vtexts(char model_num)
{
  short curr = model_base_nums[model_num];
  ....
  if (model_num >= MAX_VTEXT_OBJS)
    return;
}

Qt

V781 CWE-129 The value of the 'signal' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 397, 413. qobject.cpp 397


void QObjectPrivate::addConnection(int signal, Connection *c)
{
  ....
  if (signal >= connectionLists->count())
    connectionLists->resize(signal + 1);

  ConnectionList &connectionList = (*connectionLists)[signal];
  ....
  if (signal < 0) {
  ....
}

Haiku Operation System

V781 The value of the 'vector' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 802, 805. oce_if.c 802


#define OCE_MAX_EQ 32

typedef struct oce_softc {
  ....
  OCE_INTR_INFO intrs[OCE_MAX_EQ];
  ....
} OCE_SOFTC, *POCE_SOFTC;

static int
oce_alloc_intr(POCE_SOFTC sc, int vector, void (*isr) (void *arg, int pending))
{
  POCE_INTR_INFO ii = &sc->intrs[vector];
  int rc = 0, rr;

  if (vector >= OCE_MAX_EQ)
    return (EINVAL);
  ....
}

GCC

V781 The value of the 'best_alg->ops' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 3157, 3164. expmed.c 3157


struct algorithm
{
  struct mult_cost cost;
  short ops;
  enum alg_code op[MAX_BITS_PER_WORD];
  char log[MAX_BITS_PER_WORD];
};

static void
synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
            const struct mult_cost *cost_limit, machine_mode mode)
{
  int m;
  struct algorithm *alg_in, *best_alg;
  ....
  /* Cache the result.  */
  if (!cache_hit)
    {
      entry_ptr->t = t;
      entry_ptr->mode = mode;
      entry_ptr->speed = speed;
      entry_ptr->alg = best_alg->op[best_alg->ops];
      entry_ptr->cost.cost = best_cost.cost;
      entry_ptr->cost.latency = best_cost.latency;
    }

  /* If we are getting a too long sequence for `struct algorithm'
     to record, make this search fail.  */
  if (best_alg->ops == MAX_BITS_PER_WORD)
    return;
  ....
}

Minetest

V781 The value of the 'i' index is checked after it was used. Perhaps there is a mistake in program logic. irrString.h 572


bool equalsn(const string<T,TAlloc>& other, u32 n) const
{
  u32 i;
  for(i=0; array[i] && other[i] && i < n; ++i) // <=
    if (array[i] != other[i])
      return false;

  // if one (or both) of the strings was smaller then they
  // are only equal if they have the same length
  return (i == n) || (used == other.used);
}

Qemu

V781 The value of the 'ix' index is checked after it was used. Perhaps there is a mistake in program logic. uri.c 2110


char *uri_resolve_relative(const char *uri, const char *base)
{
  ....
  ix = pos;
  if ((ref->path[ix] == '/') && (ix > 0)) {
  ....
}

GTK

V781 [CWE-129] The value of the 'idx' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 71, 73. gtkatspiaction.c 71


static void
action_handle_method (GtkAtSpiContext        *self,
                      const char             *method_name,
                      GVariant               *parameters,
                      GDBusMethodInvocation  *invocation,
                      const Action           *actions,
                      int                     n_actions)
{
  ....
  int idx = -1;

  g_variant_get (parameters, "(i)", &idx);

  const Action *action = &actions[idx];

  if (idx >= 0 && idx < n_actions)
    g_dbus_method_invocation_return_value (
      invocation, g_variant_new ("(s)", action->name));
  else
    g_dbus_method_invocation_return_error (invocation,
                                           G_IO_ERROR,
                                           G_IO_ERROR_INVALID_ARGUMENT,
                                           "Unknown action %d",
                                           idx);
  ....
}

Similar errors can be found in some other places:

  • V781 [CWE-129] The value of the 'idx' variable is checked after it was used. Perhaps there is a mistake in program logic. Check lines: 132, 134. gtkatspiaction.c 132

libtorrent

V781 The value of the 'read_pos' index is checked after it was used. Perhaps there is a mistake in program logic. http_stream.hpp:166.


template <typename Handler>
void handshake2(error_code const& e, Handler h)
{
  ....
  std::size_t const read_pos = m_buffer.size();
  ....
  if (m_buffer[read_pos - 1] == '\n' && read_pos > 2) // <=
  {
    if (m_buffer[read_pos - 2] == '\n')
    {
      found_end = true;
    }
    else if (read_pos > 4
      && m_buffer[read_pos - 2] == '\r'
      && m_buffer[read_pos - 3] == '\n'
      && m_buffer[read_pos - 4] == '\r')
    {
      found_end = true;
    }
  }
  ....
}

TheXTech

V781 The value of the 'whatPlayer' index is checked after it was used. Perhaps there is a mistake in program logic. thextech blocks.cpp 159


if(b.ShakeY != 0 || b.ShakeY2 != 0 || b.ShakeY3 != 0)
{
  if(  b.RapidHit > 0
    && Player[whatPlayer].Character == 4 && whatPlayer > 0) // <=
  {
    b.RapidHit = (iRand() % 3) + 1;
  }
  return;
}

LLVM/Clang

V781 [CWE-20, CERT-API00-C] The value of the 'sourceDim' index is checked after it was used. Perhaps there is a mistake in program logic. ReshapeOpsUtils.cpp 49


Optional<SmallVector<ReassociationIndices>>
mlir::getReassociationIndicesForCollapse(ArrayRef<int64_t> sourceShape,
                                         ArrayRef<int64_t> targetShape) {
  unsigned sourceDim = 0;
  ....
  int64_t currTargetShape = targetShape[targetDim];
  while (sourceShape[sourceDim] != ShapedType::kDynamicSize &&
         prodOfCollapsedDims * sourceShape[sourceDim] < currTargetShape &&
         sourceDim < sourceShape.size()) {
    prodOfCollapsedDims *= sourceShape[sourceDim];
    currIndices.push_back(sourceDim++);
  }
  ....
}

Captain Blood

V781 [CWE-20, CERT-API00-C] The value of the 'start' index is checked after it was used. Perhaps there is a mistake in program logic. coreloader.h 136


__forceinline void GetBootParams(const char * bootIni)
{
  long start = 0;
  ....
  if (bootIni[start] && start > 0)
  {
    ....
  }
  ....
}

GZDoom

V781 The value of the 'len' index is checked after it was used. Perhaps there is a mistake in program logic. s_reverbedit.cpp 193


FString SuggestNewName(const ReverbContainer *env)
{
  char text[32];
  size_t len;

  strncpy(text, env->Name, 31);
  text[31] = 0;

  len = strlen(text);
  ....
  if (text[len - 1] != ' ' && len < 31)      // <=
  {
    text[len++] = ' ';
  }
}

Godot Engine

V781 The value of the 'non_op' index is checked after it was used. Perhaps there is a mistake in program logic. gdscript_highlighter.cpp 370


Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl
                                                             (int p_line)
{
  const String &str = text_edit->get_line(p_line);
  const int line_length = str.length();
  ....
  for (int j = 0; j < line_length; ++j)
  {
    ....
    int non_op = j + 1;
    ....
    if (   is_digit(str[non_op])
        || (   str[non_op] == '.'            // <=
            && non_op < line_length          // <=
            && is_digit(str[non_op + 1]) ) )
    {
      ....
    }
    ....
  }
  ....
}

DPDK

V781 The value of the 'ent' index is checked after it was used. Perhaps there is a mistake in program logic. cmdline_flow.c 12870


static int
comp_names_to_index(struct context *ctx, const struct token *token,
        unsigned int ent, char *buf, unsigned int size,
        const char *const names[], size_t names_size)
{
  RTE_SET_USED(ctx);
  RTE_SET_USED(token);
  if (!buf)
    return names_size;
  if (names[ent] && ent < names_size)
    return rte_strscpy(buf, names[ent], size);
  return -1;
}