From a9ca346ee1cc2f8d2db1276f357110478aef8ba7 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sat, 16 Mar 2019 22:03:00 -0700 Subject: [PATCH] Fix base path in model loaders; --- src/data/modelData_gltf.c | 29 +++++++++++++++++------------ src/data/modelData_obj.c | 10 ++++++---- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/data/modelData_gltf.c b/src/data/modelData_gltf.c index 84ea02e6..7dff4bae 100644 --- a/src/data/modelData_gltf.c +++ b/src/data/modelData_gltf.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #define MAX_STACK_TOKENS 1024 @@ -120,10 +121,13 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source) { size_t jsonLength, binLength; ptrdiff_t binOffset; - char basePath[1024]; - strncpy(basePath, source->name, 1023); - char* slash = strrchr(basePath, '/'); - if (slash) *slash = 0; + char filename[1024]; + lovrAssert(strlen(source->name) < sizeof(filename), "glTF filename is too long"); + strcpy(filename, source->name); + char* slash = strrchr(filename, '/'); + char* root = slash ? (slash + 1) : filename; + size_t maxPathLength = sizeof(filename) - (root - filename); + *root = '\0'; if (glb) { gltfChunkHeader* jsonHeader = (gltfChunkHeader*) &header[1]; @@ -418,13 +422,13 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source) { } if (uri.data) { - lovrAssert(strncmp("data:", uri.data, strlen("data:")), "Base64 URIs aren't supported yet");; size_t bytesRead; - char filename[1024]; - lovrAssert(uri.length < 1024, "Buffer filename is too long"); - snprintf(filename, 1023, "%s/%.*s", basePath, (int) uri.length, uri.data); + lovrAssert(uri.length < 5 || strncmp("data:", uri.data, 5), "Base64 URIs aren't supported yet"); + lovrAssert(uri.length < maxPathLength, "Buffer filename is too long"); + strncat(filename, uri.data, uri.length); *blob = lovrBlobCreate(lovrFilesystemRead(filename, -1, &bytesRead), size, NULL); lovrAssert((*blob)->data && bytesRead == size, "Unable to read %s", filename); + *root = '\0'; } else { lovrAssert(glb, "Buffer is missing URI"); lovrRetain(source); @@ -595,19 +599,20 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source) { ModelBuffer* buffer = &model->buffers[NOM_INT(json, token)]; Blob* blob = lovrBlobCreate(buffer->data, buffer->size, NULL); *texture = lovrTextureDataCreateFromBlob(blob, false); - blob->data = NULL; // FIXME + blob->data = NULL; // XXX Blob data ownership lovrRelease(blob); } else if (STR_EQ(key, "uri")) { size_t size = 0; - char filename[1024]; gltfString uri = NOM_STR(json, token); - lovrAssert(strncmp("data:", uri.data, strlen("data:")), "Base64 URIs aren't supported yet"); - snprintf(filename, 1024, "%s/%.*s%c", basePath, (int) uri.length, uri.data, 0); + lovrAssert(uri.length < 5 || strncmp("data:", uri.data, 5), "Base64 URIs aren't supported yet"); + lovrAssert(uri.length < maxPathLength, "Image filename is too long"); + strncat(filename, uri.data, uri.length); void* data = lovrFilesystemRead(filename, -1, &size); lovrAssert(data && size > 0, "Unable to read texture from '%s'", filename); Blob* blob = lovrBlobCreate(data, size, NULL); *texture = lovrTextureDataCreateFromBlob(blob, false); lovrRelease(blob); + *root = '\0'; } else { token += NOM_VALUE(json, token); } diff --git a/src/data/modelData_obj.c b/src/data/modelData_obj.c index a8910c96..fc3e6070 100644 --- a/src/data/modelData_obj.c +++ b/src/data/modelData_obj.c @@ -52,7 +52,7 @@ static void parseMtl(char* path, vec_void_t* textures, vec_material_t* materials bool hasFilename = sscanf(s + 7, "%s\n%n", filename, &lineLength); lovrAssert(hasFilename, "Bad OBJ: Expected a texture filename"); char path[1024]; - snprintf(path, 1023, "%s/%s", base, filename); + snprintf(path, 1023, "%s%s", base, filename); size_t size = 0; void* data = lovrFilesystemRead(path, -1, &size); lovrAssert(data && size > 0, "Unable to read texture from %s", path); @@ -113,9 +113,11 @@ ModelData* lovrModelDataInitObj(ModelData* model, Blob* source) { vec_push(&groups, ((objGroup) { .material = -1 })); char base[1024]; - strncpy(base, source->name, 1023); + lovrAssert(strlen(source->name) < sizeof(base), "OBJ filename is too long"); + strcpy(base, source->name); char* slash = strrchr(base, '/'); - if (slash) *slash = 0; + char* root = slash ? (slash + 1) : base; + *root = '\0'; while (length > 0) { int lineLength = 0; @@ -182,7 +184,7 @@ ModelData* lovrModelDataInitObj(ModelData* model, Blob* source) { bool hasName = sscanf(data + 7, "%1024s\n%n", filename, &lineLength); lovrAssert(hasName, "Bad OBJ: Expected filename after mtllib"); char path[1024]; - snprintf(path, 1023, "%s/%s", base, filename); + snprintf(path, 1023, "%s%s", base, filename); parseMtl(path, &textures, &materials, &materialNames, base); } else if (STARTS_WITH(data, "usemtl ")) { char name[128];