Skip to content

Commit 774bb4d

Browse files
authored
feat: Fuzz Testing PythonParser (#3737)
Signed-off-by: Joydeep Tripathy <[email protected]>
1 parent 60e74fb commit 774bb4d

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

fuzz/fuzz_pkg_info.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright (C) 2023 Intel Corporation
2+
# SPDX-License-Identifier: GPL-3.0-or-later
3+
4+
import sys
5+
import tempfile
6+
from pathlib import Path
7+
8+
import atheris
9+
import atheris_libprotobuf_mutator
10+
from google.protobuf.json_format import MessageToDict
11+
12+
import fuzz.generated.pkg_info_pb2 as pkg_info_pb2
13+
from cve_bin_tool.cvedb import CVEDB
14+
from cve_bin_tool.log import LOGGER
15+
16+
with atheris.instrument_imports():
17+
from cve_bin_tool.parsers.python import PythonParser
18+
19+
cve_db = CVEDB()
20+
logger = LOGGER.getChild("Fuzz")
21+
22+
23+
def PkgInfoBuilder(data):
24+
"""Convert the Protobuf message to a dictionary"""
25+
json_data = MessageToDict(
26+
data, preserving_proto_field_name=True, including_default_value_fields=True
27+
)
28+
29+
with open(file_path, "w") as f:
30+
# Writing each field of PKG-INFO
31+
f.write(f"Metadata-Version: {json_data.get('metadata_version', '2.1')}\n")
32+
f.write(f"Name: {json_data.get('name', '')}\n")
33+
f.write(f"Version: {json_data.get('version', '')}\n")
34+
f.write(f"Summary: {json_data.get('summary', '')}\n")
35+
f.write(f"Home-page: {json_data.get('home_page', '')}\n")
36+
f.write(f"Author: {json_data.get('author', '')}\n")
37+
f.write(f"Author-email: {json_data.get('author_email', '')}\n")
38+
f.write(f"License: {json_data.get('license', '')}\n")
39+
40+
# Writing keywords
41+
if "keywords" in json_data:
42+
f.write(f"Keywords: {', '.join(json_data['keywords'])}\n")
43+
44+
# Writing classifiers
45+
for classifier in json_data.get("classifiers", []):
46+
f.write(f"Classifier: {classifier}\n")
47+
48+
f.write(f"Requires-Python: {json_data.get('requires_python', '')}\n")
49+
f.write(f"License-File: {json_data.get('license_file', '')}\n")
50+
51+
# Writing requires-dist
52+
for req_dist in json_data.get("requires_dist", []):
53+
f.write(f"Requires-Dist: {req_dist}\n")
54+
55+
# Writing provides-extra
56+
for provides in json_data.get("provides_extra", []):
57+
f.write(f"Provides-Extra: {provides}\n")
58+
59+
60+
def TestParseData(data):
61+
try:
62+
PkgInfoBuilder(data)
63+
64+
python_parser = PythonParser(cve_db, logger)
65+
python_parser.run_checker(file_path)
66+
67+
except SystemExit:
68+
return
69+
70+
71+
file_path = str(Path(tempfile.mkdtemp(prefix="cve-bin-tool-")) / "PKG.INFO")
72+
73+
atheris_libprotobuf_mutator.Setup(sys.argv, TestParseData, proto=pkg_info_pb2.PkgInfo)
74+
atheris.Fuzz()

fuzz/generated/pkg_info_pb2.py

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fuzz/proto_files/pkg_info.proto

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright(C) 2023 Intel Corporation
2+
// SPDX-License-Identifier: GPL-3.0-or -later
3+
4+
syntax = "proto3";
5+
6+
// Represents the PKG-INFO file structure for a Python package
7+
message PkgInfo {
8+
string metadata_version = 1;
9+
string name = 2;
10+
string version = 3;
11+
string summary = 4;
12+
string home_page = 5;
13+
string author = 6;
14+
string author_email = 7;
15+
string license = 8;
16+
repeated string keywords = 9;
17+
repeated string classifiers = 10;
18+
string requires_python = 11;
19+
string license_file = 12;
20+
repeated string requires_dist = 13;
21+
repeated string provides_extra = 14;
22+
}

0 commit comments

Comments
 (0)