Open aT0ngMu opened 1 year ago
Hi, unfortunately the doxygen tool is still very experimental -- there are some edge cases that it does not properly handle, particularly with namespaces.
The issue with:
[!] Error while parsing: AC3DImporter()
'NoneType' object has no attribute 'base_type'
is caused by this struct definition:
struct_Assimp::AC3DImporter:
default_destructor: true
headers:
- ACLoader.h
methods:
- AC3DImporter()
- ~AC3DImporter() override
- bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const
override
name: Assimp::AC3DImporter
static_methods: []
type: struct
In order to find the constructor and destructor, the gfuzz tool expects the function name to match either <struct_name>
or ~<struct_name>
. Since the name is defined with a namespace as Assimp::AC3DImporter
, it expects the constructor to look like: Assimp::AC3DImporter()
Unfortunately C++ is complex enough that there are still a fair number of edge cases like this in graphfuzz.
In general, I wouldn't recommend trying to harness the entire API at once. Rather, the strategy I used was to use the doxygen tool to generate a helpful starting point, then I copy and pasted the structs/classes I was interested in fuzzing in a new schema.
It definitely looks like Assimp could benefit from API fuzzing. I would recommend starting with one or two core structs and try to get those working in an isolated harness. Then you can try to expand the harness with new structs.
Let me know if you run into any specific issues trying to do this!
Hi, unfortunately the doxygen tool is still very experimental -- there are some edge cases that it does not properly handle, particularly with namespaces.
The issue with:
[!] Error while parsing: AC3DImporter() 'NoneType' object has no attribute 'base_type'
is caused by this struct definition:
struct_Assimp::AC3DImporter: default_destructor: true headers: - ACLoader.h methods: - AC3DImporter() - ~AC3DImporter() override - bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override name: Assimp::AC3DImporter static_methods: [] type: struct
In order to find the constructor and destructor, the gfuzz tool expects the function name to match either
<struct_name>
or~<struct_name>
. Since the name is defined with a namespace asAssimp::AC3DImporter
, it expects the constructor to look like:Assimp::AC3DImporter()
Unfortunately C++ is complex enough that there are still a fair number of edge cases like this in graphfuzz.
In general, I wouldn't recommend trying to harness the entire API at once. Rather, the strategy I used was to use the doxygen tool to generate a helpful starting point, then I copy and pasted the structs/classes I was interested in fuzzing in a new schema.
It definitely looks like Assimp could benefit from API fuzzing. I would recommend starting with one or two core structs and try to get those working in an isolated harness. Then you can try to expand the harness with new structs.
Let me know if you run into any specific issues trying to do this!
Thank you very much for your explanation!! But I'm still encountering some issues.
Here are my steps:
schema.yaml
for the entire source code of the assimp library.
gfuzz doxygen --inputs ./sourceCode/assimp --output ./assimp_output
gfuzz schema infer ./assimp_output/xml ./assimp_output/schema.yaml
gfuzz gen cpp ./assimp_output/schema.yaml .
schema.yaml
and paste them into custom.yaml. custom.yaml.
gfuzz gen cpp ./custom.yaml .
clang++ -I ../assimp/include -I ../assimp/code/Common -I ../assimp/include/assimp fuzz_exec.cpp ../assimp/lib/libassimp.a -o fuzz_exec -lz -lgraphfuzz -lprotobuf -fsanitize=address,fuzzer
./fuzz_exec
The error message after running the harness is as follows: [] Loading: schema.json [] GraphFuzz: loading trees from cache... [!] No initializer tree for type: "aiScene" (type: 87) [] After validation: total scopes: 19 [] After validation: usable scopes: 18 [!] Schema is invalid. (Run with "--graphfuzz_ignore_invalid" to continue with usable scopes).
I looked at the source code of GraphFuzz, and it seems that if initializer
or finalizer
for a struct
is empty, it cannot pass validation
. I'm not sure how to construct schema.yaml
to make initializers
or finalizers
valid. Do you have any better suggestions?
Hi, could you share your custom.yaml file? The error message No initializer tree for type: "aiScene"
means that GraphFuzz could not figure out a way to construct the struct aiScene
.
I'm very sorry, I forgot to upload. The compressed file contains the relevant files. assimp_output.tar.gz
Hi, GraphFuzz is a very effective testing library API's work!!!! However, when I tested the assimp library on GraphFuzz, I encountered some issues.
Here are my steps:
1. git clone --depth=1 https:github.com/assimp/assimp.git
2. mkdir assimp_output
3. gfuzz doxygen --inputs ./sourceCode/assimp --output ./assimp_output
4. gfuzz schema infer ./assimp_output/xml ./assimp_output/schema.yaml
5. gfuzz gen cpp ./assimp_output/schema.yaml .
When I ran the fifth command, I received the following error message:
[!] Error while parsing: AC3DImporter() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ~AC3DImporter() override 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Material() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Object() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Surface() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ~AMFImporter() override 'NoneType' object has no attribute 'base_type' [!] Error while parsing: BaseNode(Type _mType, const std::string &name) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Bone(const std::string &name) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Camera(const std::string &name) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Light(const std::string &name) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Material(const std::string &name) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Mesh(const std::string &name) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Parser(const char szFile, unsigned int fileFormatDefault) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ASEImporter() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: AttachmentInfo() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: AttachmentInfo(aiScene _scene, aiNode *_attachToNode) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ~B3DImporter() override 'NoneType' object has no attribute 'base_type' [!] Error while parsing: BVHLoader() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ~BVHLoader() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ~BaseImporter() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ~BaseProcess() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ~BatchLoader() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Base() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ConversionData(const FileDatabase &db) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: CustomDataLayer() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: DNAParser(FileDatabase &db) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ElemBase() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: FileDatabase() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: FileOffset() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: MTFace() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: MVert() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: Object() 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ObjectCache(const FileDatabase &db) 'NoneType' object has no attribute 'base_type' [!] Error while parsing: ObjectCache(const FileDatabase &) 'NoneType' object has no attribute 'base_type' Traceback (most recent call last): File "/home/server1/.local/bin/gfuzz", line 8, in
sys.exit(main())
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/cli.py", line 23, in main
options[args.mode].execute(args)
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/cliopt.py", line 17, in execute
res = self._execute_fn(args)
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/gen/gen.py", line 24, in execute
OPTIONS[args.gen_mode].execute(args)
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/cliopt.py", line 17, in execute
res = self._execute_fn(args)
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/gen/cpp/gen_cpp.py", line 1328, in execute
generate_harness(
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/gen/cpp/gen_cpp.py", line 1247, in generate_harness
raw_scopes, max_num, errors = collect_scopes(schema, ignore_keywords, generate_dry)
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/gen/cpp/gen_cpp.py", line 1026, in collect_scopes
scopes.append(CPPScope.destructor_for(schema, obj))
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/gen/cpp/gen_cpp.py", line 319, in destructor_for
return CPPScope.from_signature(schema, parent, sig, False)
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/gen/cpp/gen_cpp.py", line 337, in from_signature
scope_type = _classify(parent, sig, is_static)
File "/home/server1/.local/lib/python3.8/site-packages/gfuzz/commands/gen/cpp/gen_cpp.py", line 251, in _classify
if sig.func_name.name == obj_name and not is_static:
AttributeError: 'NoneType' object has no attribute 'func_name'
Is it due to my improper usage or some other reason? Looking forward to your assistance and your message!!! Thanks!!