Skip to content

VNX-686: Function Call With Incorrect Argument Type

Detects C and C++ printf- and scanf-family calls whose argument type visibly mismatches its conversion: size_t to %d, non-strings to %s, std::string without .c_str(), and scanf targets passed by value.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-686
Severity Low
SARIF level note
Kind sast
Languages C, C++
CWE CWE-686
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L
Tags format-argument-type cwe-686
Source internal/sast/rules/vnx-686.rego

Overview

VNX-686 maps to CWE-686: Function Call With Incorrect Argument Type. A variadic call reads each argument as the type its conversion names. Passing a 64-bit size_t to %d, an integer to %s or a std::string object to %s is undefined behaviour: the call reads the wrong bytes, or dereferences an integer as a pointer.

What Gets Flagged

printf("name is %d bytes\n", strlen(name));   // FLAGGED: size_t to %d
printf("status %s\n", 404);                   // FLAGGED: integer to %s
sprintf(buf, "%d items", "ten");              // FLAGGED: string to %d
printf("%f\n", 1);                            // FLAGGED: int to %f
scanf("%d", count);                           // FLAGGED: int count; needs &count

size_t len = strlen(s);
double ratio = 0.5;
printf("len=%d\n", len);                      // FLAGGED: declared size_t
printf("ratio=%d\n", ratio);                  // FLAGGED: declared double
printf("name=%s id=%d\n", name, id);          // FLAGGED: name is a std::string
std::printf("user %s\n", std::to_string(id)); // FLAGGED

What Is Not Flagged

  • %zu/%zd and %lu, explicit casts, and .c_str().
  • Pointers and arrays passed to scanf.
  • Calls whose argument count differs from the format (VNX-685 reports those), calls split over several lines, and macro-built formats.
  • Comments and string literals.

Remediation

Use the conversion that matches the type (%zu for size_t), pass .c_str() for C++ strings and &var to scanf, and compile with -Wall -Wformat=2.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-686
// nosec vnx-686

Or record an ignore rule: vulnetix ignore add --rule vnx-686 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-686.rego, cli/internal/sast/docs/vnx-686.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.