-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expected error handling semantics? #6
Comments
Possibly related question (I hope it's okay to post it here): how will cgltf be handling out-of-bounds accessors / buffer views? This was one of the major pain points with tinygltf, where a file with malformed accessor / buffer view offsets would still parse as if everything was okay, requiring the user to check it on every access instead. In my opinion it would make sense to do such checks in cgltf_parse directly, to avoid accidental unsafe memory accesses on user side when a broken file is encountered. |
I think this is the best approach. We probably should introduce some sort of |
Yeah, I can certainly see that calling I kind of like the idea that you never get access to the Anyway, I think from an implementation point-of-view your second possibility would be best, @zeux . If it wasn't possible to call So, my suggestion is that we should make sure all pointers are always initialized to Or am I missing something? @mosra It would definitely be a good idea to catch this kind of error while fixing up the pointers. What kind of response would you expect in this case? |
Yeah I was planning to move to zero-initialized everything anyway. Having cgltf_free be safe to call always would be good. But just to be clear - will we force the user to do that, or will we do the cleanup ourselves? The current examples in the README suggest that cgltf_free shouldn't be called on error. I'll think about the interface tradeoff a bit more. For indices being in-bounds vs not, first step is to make sure that cgltf_data itself is well-formed; right now for example out-of-bounds indices in the input gltf will create out-of-bounds pointers. I plan to fix it by changing the relocation stage to fail in that case. Once we're fuzz-safe for the basic parser we can discuss other validation needs, maybe it would be good to file a separate issue describing the desired behavior. |
In the end you're trading a lot usability and possibly UB against a small (if any; depends on the scenario) performance improvement. The allocation of |
Additional thoughts on deeper validation: There's many many conditions that could cause the user program that assumes a well-formed GLTF to cause memory safety issues. There are basic examples, like "number of items in all vertex streams in a primitive must coincide". There are examples like "all indices in the accessor point into a valid range as defined by vertex streams" that are more complex (see below). And then there's "scene nodes form a tree" - cycles in node tree would cause most programs to misbehave. So I'd suggest implementing a separate function, cgltf_validate, that takes a parsed cgltf_data and performs deeper validation on it. This function will need access to buffer data to validate indices - we could pass an additional array of buffer pointers to this function so that it can query them. This should be separate from basic memory safety of the parser itself. |
And yeah I like the idea of changing the interface to return a pointer to cgltf_data. That would make the interface more obvious - you’d only need to call free on a non-NULL pointer, and we wouldn’t return a non-NULL pointer for failed parse. It’s a breaking change but seems worth it. |
Ok, this all sounds good to me:
|
Yeah I intend to reuse cgltf_free internally and maintain parse data in a deallocatable state at all times. This sounds good; I’ll create a separate issue for thorough validation and work on the interface changes separately. |
I'd like to make sure that errors are handled consistently, with an eventual goal of fuzzing the parser to make sure it is memory safe.
When cgltf_parse returns cgltf_result_success, cgltf_free frees all the data correctly (hopefully? :)).
However, when cgltf_parse returns an error, several issues may occur:
I'd like to clean that up but I'm not sure what the expectations are. I can see two possibilities:
What's the expected behavior here?
The text was updated successfully, but these errors were encountered: