Skip to content

Cpp

This page curates a list of example ast-grep rules to check and to rewrite Cpp code.

Reuse Cpp rules with C

Cpp is a superset of C, so you can reuse Cpp rules with C code. The languageGlobs option can force ast-grep to parse .c files as Cpp.

Fix Format String Vulnerability Has Fix

Description

The Format String exploit occurs when the submitted data of an input string is evaluated as a command by the application.

For example, using sprintf(s, var) can lead to format string vulnerabilities if var contains user-controlled data. This can be exploited to execute arbitrary code. By explicitly specifying the format string as "%s", you ensure that var is treated as a string, mitigating this risk.

YAML

yaml
id: fix-format-security-error
language: Cpp
rule:
  pattern: $PRINTF($S, $VAR)
constraints:
  PRINTF: # a format string function
    { regex: "^sprintf|fprintf$" }
  VAR: # not a literal string
    not:
      any:
      - { kind: string_literal }
      - { kind: concatenated_string }
fix: $PRINTF($S, "%s", $VAR)

Example

cpp
// Error
fprintf(stderr, out);
sprintf(&buffer[2], obj->Text);
sprintf(buf1, Text_String(TXT_WAITING_FOR_CONNECTIONS));
// OK
fprintf(stderr, "%s", out);
sprintf(&buffer[2], "%s", obj->Text);
sprintf(buf1, "%s", Text_String(TXT_WAITING_FOR_CONNECTIONS));

Diff

js
// Error
fprintf(stderr, out); 
fprintf(stderr, "%s", out); 
sprintf(&buffer[2], obj->Text); 
sprintf(&buffer[2], "%s", obj->Text); 
sprintf(buf1, Text_String(TXT_WAITING_FOR_CONNECTIONS)); 
sprintf(buf1, "%s", Text_String(TXT_WAITING_FOR_CONNECTIONS)); 
// OK
fprintf(stderr, "%s", out);
sprintf(&buffer[2], "%s", obj->Text);
sprintf(buf1, "%s", Text_String(TXT_WAITING_FOR_CONNECTIONS));

Contributed by

xiaoxiangmoe

Find Struct Inheritance

Description

ast-grep's pattern is AST based. A code snippet like struct $SOMETHING: $INHERITS will not work because it does not have a correct AST structure. The correct pattern should spell out the full syntax like struct $SOMETHING: $INHERITS { $$$BODY; }.

Compare the ast structure below to see the difference, especially the ERROR node. You can also use the playground's pattern panel to debug.

shell
ERROR
  $SOMETHING
  base_class_clause
    $INHERITS
shell
struct_specifier
  $SOMETHING
  base_class_clause
    $INHERITS
  field_declaration_list
    field_declaration
      $$$BODY

If it is not possible to write a full pattern, YAML rule is a better choice.

Pattern

shell
ast-grep --lang cpp --pattern '
struct $SOMETHING: $INHERITS { $$$BODY; }'

Example

cpp
struct Bar: Baz {
  int a, b;
}

Contributed by

Inspired by this tweet

Made with ❤️ with Rust