Repository navigation
[io] validate vertex lines in OBJReader::read - #6493
Merged
mvieth merged 2 commits intoOct 28, 2026
Merged
Conversation
readHeader sizes cloud.data from the lines it counts as vertices, but the read overloads also store a "v" line separated by a tab or carriage return, writing past the end of cloud.data. Reject vertex lines beyond the header count or with fewer than three coordinates, reject short vertex normal lines, cap the texture coordinate loop at three values, and count tab separated vertices in readHeader so such files keep loading.
mvieth
reviewed
Oct 27, 2026
| { | ||
| Eigen::Vector3f c (0, 0, 0); | ||
| for (std::size_t i = 1; i < st.size (); ++i) | ||
| for (std::size_t i = 1; i < st.size () && i < 4; ++i) |
Member
There was a problem hiding this comment.
Is there a reason why you chose to not error-out here if st.size() > 4? E.g. vt 1.0 2.0 3.0 4.0 is invalid obj format, right? Might be better to display an error and quit, instead of silently ignoring the extra values?
Contributor
Author
There was a problem hiding this comment.
No strong reason, I was only after the out-of-bounds write. You're right that vt takes at most u, v, w, so it now prints an error and returns -1 when there are more than three values, the same way the short v/vn lines are handled. Updated the test so vt 0.0 0.0 1.0 1.0 is expected to fail for the TextureMesh reader.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AddressSanitizer,
OBJReader::read (file, PCLPointCloud2&)on a file containingv 0 0 0followed byv\t1 2 3:readHeadersizescloud.datafrom the lines it counts as vertices, and it only counts a line whenline[1] == ' '. The body loops of all threereadoverloads tokenise on tab, CR and space instead, so a vertex line separated by a tab or carriage return is missing from the count but still written atv_idx * point_step, past the end ofcloud.data. The PolygonMesh and TextureMesh overloads fail the same way (obj_io.cpp:1079 and :813 before the patch). The same loops also readst[1..3]onvandvnlines without checking the token count (v 1 2is an out-of-bounds read under ASan), and the TextureMeshvtloop stores every token into anEigen::Vector3f, so avtline with more than three values writes past it in release builds.Each
vline is now checked against the header count and its token count before the write, shortvnlines are rejected, thevtloop stops after three values, andreadHeaderalso counts tab separated vertices so those files load instead of being rejected. This complements the face index checks from #6448, which coveredflines but not the vertex lines that fillcloud.data. The newOBJReadMalformedVertexLinestest fails under ASan before the patch and passes after; I ran it together with the existing OBJ tests from test_io.cpp against obj_io.cpp in a standalone ASan build.