Fix buffer overrun when parsing 'l' line.
This commit is contained in:
@@ -137,8 +137,10 @@ static void PrintInfo(const tinyobj::attrib_t& attrib,
|
|||||||
for (size_t i = 0; i < shapes.size(); i++) {
|
for (size_t i = 0; i < shapes.size(); i++) {
|
||||||
printf("shape[%ld].name = %s\n", static_cast<long>(i),
|
printf("shape[%ld].name = %s\n", static_cast<long>(i),
|
||||||
shapes[i].name.c_str());
|
shapes[i].name.c_str());
|
||||||
printf("Size of shape[%ld].indices: %lu\n", static_cast<long>(i),
|
printf("Size of shape[%ld].mesh.indices: %lu\n", static_cast<long>(i),
|
||||||
static_cast<unsigned long>(shapes[i].mesh.indices.size()));
|
static_cast<unsigned long>(shapes[i].mesh.indices.size()));
|
||||||
|
printf("Size of shape[%ld].path.indices: %lu\n", static_cast<long>(i),
|
||||||
|
static_cast<unsigned long>(shapes[i].path.indices.size()));
|
||||||
|
|
||||||
size_t index_offset = 0;
|
size_t index_offset = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ THE SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// version 1.2.1 : Added initial support for line('l') primitive(PR #178)
|
||||||
// version 1.2.0 : Hardened implementation(#175)
|
// version 1.2.0 : Hardened implementation(#175)
|
||||||
// version 1.1.1 : Support smoothing groups(#162)
|
// version 1.1.1 : Support smoothing groups(#162)
|
||||||
// version 1.1.0 : Support parsing vertex color(#144)
|
// version 1.1.0 : Support parsing vertex color(#144)
|
||||||
@@ -377,8 +378,8 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <utility>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -1011,8 +1012,7 @@ static void InitMaterial(material_t *material) {
|
|||||||
|
|
||||||
// code from https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html
|
// code from https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static int pnpoly(int nvert, T *vertx, T *verty, T testx,
|
static int pnpoly(int nvert, T *vertx, T *verty, T testx, T testy) {
|
||||||
T testy) {
|
|
||||||
int i, j, c = 0;
|
int i, j, c = 0;
|
||||||
for (i = 0, j = nvert - 1; i < nvert; j = i++) {
|
for (i = 0, j = nvert - 1; i < nvert; j = i++) {
|
||||||
if (((verty[i] > testy) != (verty[j] > testy)) &&
|
if (((verty[i] > testy) != (verty[j] > testy)) &&
|
||||||
@@ -1029,18 +1029,14 @@ static bool exportGroupsToShape(shape_t *shape,
|
|||||||
const std::vector<face_t> &faceGroup,
|
const std::vector<face_t> &faceGroup,
|
||||||
std::vector<int> &lineGroup,
|
std::vector<int> &lineGroup,
|
||||||
const std::vector<tag_t> &tags,
|
const std::vector<tag_t> &tags,
|
||||||
const int material_id,
|
const int material_id, const std::string &name,
|
||||||
const std::string &name, bool triangulate,
|
bool triangulate,
|
||||||
const std::vector<real_t> &v) {
|
const std::vector<real_t> &v) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (faceGroup.empty() && lineGroup.empty()) {
|
if (faceGroup.empty() && lineGroup.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!faceGroup.empty()) {
|
if (!faceGroup.empty()) {
|
||||||
|
|
||||||
// Flatten vertices and indices
|
// Flatten vertices and indices
|
||||||
for (size_t i = 0; i < faceGroup.size(); i++) {
|
for (size_t i = 0; i < faceGroup.size(); i++) {
|
||||||
const face_t &face = faceGroup[i];
|
const face_t &face = faceGroup[i];
|
||||||
@@ -1067,8 +1063,7 @@ static bool exportGroupsToShape(shape_t *shape,
|
|||||||
size_t vi1 = size_t(i1.v_idx);
|
size_t vi1 = size_t(i1.v_idx);
|
||||||
size_t vi2 = size_t(i2.v_idx);
|
size_t vi2 = size_t(i2.v_idx);
|
||||||
|
|
||||||
if (((3 * vi0 + 2) >= v.size()) ||
|
if (((3 * vi0 + 2) >= v.size()) || ((3 * vi1 + 2) >= v.size()) ||
|
||||||
((3 * vi1 + 2) >= v.size()) ||
|
|
||||||
((3 * vi2 + 2) >= v.size())) {
|
((3 * vi2 + 2) >= v.size())) {
|
||||||
// Invalid triangle.
|
// Invalid triangle.
|
||||||
// FIXME(syoyo): Is it ok to simply skip this invalid triangle?
|
// FIXME(syoyo): Is it ok to simply skip this invalid triangle?
|
||||||
@@ -1124,8 +1119,8 @@ static bool exportGroupsToShape(shape_t *shape,
|
|||||||
area += (v0x * v1y - v0y * v1x) * static_cast<real_t>(0.5);
|
area += (v0x * v1y - v0y * v1x) * static_cast<real_t>(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxRounds =
|
int maxRounds = 10; // arbitrary max loop count to protect against
|
||||||
10; // arbitrary max loop count to protect against unexpected errors
|
// unexpected errors
|
||||||
|
|
||||||
face_t remainingFace = face; // copy
|
face_t remainingFace = face; // copy
|
||||||
size_t guess_vert = 0;
|
size_t guess_vert = 0;
|
||||||
@@ -1172,9 +1167,7 @@ static bool exportGroupsToShape(shape_t *shape,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ovi = size_t(
|
size_t ovi = size_t(remainingFace.vertex_indices[idx].v_idx);
|
||||||
remainingFace.vertex_indices[idx]
|
|
||||||
.v_idx);
|
|
||||||
|
|
||||||
if (((ovi * 3 + axes[0]) >= v.size()) ||
|
if (((ovi * 3 + axes[0]) >= v.size()) ||
|
||||||
((ovi * 3 + axes[1]) >= v.size())) {
|
((ovi * 3 + axes[1]) >= v.size())) {
|
||||||
@@ -1272,7 +1265,6 @@ static bool exportGroupsToShape(shape_t *shape,
|
|||||||
shape->mesh.tags = tags;
|
shape->mesh.tags = tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!lineGroup.empty()) {
|
if (!lineGroup.empty()) {
|
||||||
shape->path.indices.swap(lineGroup);
|
shape->path.indices.swap(lineGroup);
|
||||||
}
|
}
|
||||||
@@ -1765,8 +1757,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
#else
|
#else
|
||||||
const char dirsep = '\\';
|
const char dirsep = '\\';
|
||||||
#endif
|
#endif
|
||||||
if (baseDir[baseDir.length() - 1] != dirsep)
|
if (baseDir[baseDir.length() - 1] != dirsep) baseDir += dirsep;
|
||||||
baseDir += dirsep;
|
|
||||||
}
|
}
|
||||||
MaterialFileReader matFileReader(baseDir);
|
MaterialFileReader matFileReader(baseDir);
|
||||||
|
|
||||||
@@ -1874,8 +1865,9 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
// get index from string
|
// get index from string
|
||||||
int idx;
|
int idx;
|
||||||
fixIndex(parseInt(&token), 0, &idx);
|
fixIndex(parseInt(&token), 0, &idx);
|
||||||
// move to next space or end of string (\0 / \n)
|
|
||||||
token += strcspn(token, " \t\r")+1;
|
size_t n = strspn(token, " \t\r");
|
||||||
|
token += n;
|
||||||
|
|
||||||
if (!end_line_bit) {
|
if (!end_line_bit) {
|
||||||
line_cache.idx0 = idx;
|
line_cache.idx0 = idx;
|
||||||
@@ -1995,8 +1987,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
// group name
|
// group name
|
||||||
if (token[0] == 'g' && IS_SPACE((token[1]))) {
|
if (token[0] == 'g' && IS_SPACE((token[1]))) {
|
||||||
// flush previous face group.
|
// flush previous face group.
|
||||||
bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name,
|
bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags,
|
||||||
triangulate, v);
|
material, name, triangulate, v);
|
||||||
(void)ret; // return value not used.
|
(void)ret; // return value not used.
|
||||||
|
|
||||||
if (shape.mesh.indices.size() > 0) {
|
if (shape.mesh.indices.size() > 0) {
|
||||||
@@ -2032,8 +2024,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
// object name
|
// object name
|
||||||
if (token[0] == 'o' && IS_SPACE((token[1]))) {
|
if (token[0] == 'o' && IS_SPACE((token[1]))) {
|
||||||
// flush previous face group.
|
// flush previous face group.
|
||||||
bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name,
|
bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags,
|
||||||
triangulate, v);
|
material, name, triangulate, v);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
shapes->push_back(shape);
|
shapes->push_back(shape);
|
||||||
}
|
}
|
||||||
@@ -2140,8 +2132,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
// Ignore unknown command.
|
// Ignore unknown command.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name,
|
bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material,
|
||||||
triangulate, v);
|
name, triangulate, v);
|
||||||
// exportGroupsToShape return false when `usemtl` is called in the last
|
// exportGroupsToShape return false when `usemtl` is called in the last
|
||||||
// line.
|
// line.
|
||||||
// we also add `shape` to `shapes` when `shape.mesh` has already some
|
// we also add `shape` to `shapes` when `shape.mesh` has already some
|
||||||
|
|||||||
Reference in New Issue
Block a user