fix: Crash in 3D Visualizer, improved error messages (#2062)
The recently added data checks allowed invalid sized vertex arrays to be used as if they were valid making ImHex crash. Moved all the error messages into localization strings for translation.
This commit is contained in:
parent
71e1465524
commit
8abaafab79
@ -7,6 +7,17 @@
|
||||
"hex.visualizers.pl_visualizer.3d.light_position": "Light Position",
|
||||
"hex.visualizers.pl_visualizer.3d.ambient_brightness": "Ambient Brightness",
|
||||
"hex.visualizers.pl_visualizer.3d.diffuse_brightness": "Diffuse Brightness",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_count": "{} count must be a multiple of {}",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_not_empty": "{} can't be empty",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_expected": "Expected {} but got {}",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_positions": "Positions",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_vertex_count": "Error: Vertex count must be a multiple of 3",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_colors": "Colors",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_normals": "Normals",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_uv_coords": "Texture Coordinates",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_index_count": "Error: Index count must be a multiple of 3",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_invalid_indices": "Error: Indices must be between 0 and the number of vertices minus one. Invalid indices: ",
|
||||
"hex.visualizers.pl_visualizer.3d.error_message_for_vertex_count": " for {} vertices",
|
||||
"hex.visualizers.pl_visualizer.3d.specular_brightness": "Specular Brightness",
|
||||
"hex.visualizers.pl_visualizer.3d.object_reflectiveness": "Object Reflectiveness",
|
||||
"hex.visualizers.pl_visualizer.3d.light_color": "Light Color",
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include <romfs/romfs.hpp>
|
||||
#include <numeric>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
namespace hex::plugin::visualizers {
|
||||
|
||||
@ -345,16 +344,16 @@ namespace hex::plugin::visualizers {
|
||||
bool validateVector(const std::vector<float> &vector, u32 vertexCount, u32 divisor, const std::string &name,std::string &errorMessage) {
|
||||
if (!vector.empty()) {
|
||||
if (vector.size() % divisor != 0) {
|
||||
errorMessage = name + " must be a multiple of " + std::to_string(divisor);
|
||||
errorMessage = hex::format("hex.visualizers.pl_visualizer.3d.error_message_count"_lang, name , std::to_string(divisor));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
errorMessage = name + " can't be empty";
|
||||
errorMessage = hex::format("hex.visualizers.pl_visualizer.3d.error_message_not_empty"_lang, name);
|
||||
return false;
|
||||
}
|
||||
auto vectorCount = vector.size()/divisor;
|
||||
if (vectorCount != vertexCount) {
|
||||
errorMessage = hex::format("Expected {} colors, got {}", vertexCount, vectorCount);
|
||||
errorMessage = hex::format("hex.visualizers.pl_visualizer.3d.error_message_expected"_lang, std::to_string(vertexCount), std::to_string(vectorCount));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -375,27 +374,26 @@ namespace hex::plugin::visualizers {
|
||||
if (indexType != IndexType::Undefined && !vectors.indices.empty())
|
||||
buffers.indices = gl::Buffer<T>(gl::BufferType::Index, vectors.indices);
|
||||
|
||||
if (validateVector(vectors.vertices, vertexCount, 3, "Positions", errorMessage)) {
|
||||
if ((indexType == IndexType::Undefined || vectors.indices.empty()) && vertexCount % 3 != 0) {
|
||||
throw std::runtime_error("Error: Vertex count must be a multiple of 3");
|
||||
} else
|
||||
buffers.vertices = gl::Buffer<float>(gl::BufferType::Vertex, vectors.vertices);
|
||||
} else {
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
if (validateVector(vectors.colors, vertexCount, 4, "Colors", errorMessage))
|
||||
if ((indexType == IndexType::Undefined || vectors.indices.empty()) && vertexCount % 3 != 0) {
|
||||
throw std::runtime_error(std::string("hex.visualizers.pl_visualizer.3d.error_message_vertex_count"_lang));
|
||||
} else
|
||||
buffers.vertices = gl::Buffer<float>(gl::BufferType::Vertex, vectors.vertices);
|
||||
|
||||
|
||||
if (validateVector(vectors.colors, vertexCount, 4, std::string("hex.visualizers.pl_visualizer.3d.error_message_colors"_lang), errorMessage))
|
||||
buffers.colors = gl::Buffer<float>(gl::BufferType::Vertex, vectors.colors);
|
||||
else {
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
if (validateVector(vectors.normals, vertexCount, 3, "Normals", errorMessage))
|
||||
|
||||
if (validateVector(vectors.normals, vertexCount, 3, std::string("hex.visualizers.pl_visualizer.3d.error_message_normals"_lang), errorMessage))
|
||||
buffers.normals = gl::Buffer<float>(gl::BufferType::Vertex, vectors.normals);
|
||||
else {
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
if (validateVector(vectors.uv, vertexCount, 2, "UV coordinates", errorMessage))
|
||||
if (validateVector(vectors.uv, vertexCount, 2, std::string("hex.visualizers.pl_visualizer.3d.error_message_uv_coords"_lang), errorMessage))
|
||||
buffers.uv = gl::Buffer<float>(gl::BufferType::Vertex, vectors.uv);
|
||||
else {
|
||||
throw std::runtime_error(errorMessage);
|
||||
@ -430,19 +428,17 @@ namespace hex::plugin::visualizers {
|
||||
if (indexType != IndexType::Undefined)
|
||||
lineBuffers.indices = gl::Buffer<T>(gl::BufferType::Index, lineVectors.indices);
|
||||
|
||||
if (validateVector(lineVectors.vertices, vertexCount, 3, "Positions", errorMessage)) {
|
||||
if ((indexType == IndexType::Undefined || lineVectors.indices.empty()) && vertexCount % 3 != 0) {
|
||||
throw std::runtime_error("Error: Vertex count must be a multiple of 3");
|
||||
} else
|
||||
lineBuffers.vertices = gl::Buffer<float>(gl::BufferType::Vertex, lineVectors.vertices);
|
||||
} else {
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
if (validateVector(lineVectors.colors, vertexCount, 4, "Colors", errorMessage))
|
||||
if ((indexType == IndexType::Undefined || lineVectors.indices.empty()) && vertexCount % 3 != 0) {
|
||||
throw std::runtime_error(std::string("hex.visualizers.pl_visualizer.3d.error_message_vertex_count"_lang));
|
||||
} else
|
||||
lineBuffers.vertices = gl::Buffer<float>(gl::BufferType::Vertex, lineVectors.vertices);
|
||||
|
||||
if (validateVector(lineVectors.colors, vertexCount, 4, std::string("hex.visualizers.pl_visualizer.3d.error_message_colors"_lang), errorMessage))
|
||||
lineBuffers.colors = gl::Buffer<float>(gl::BufferType::Vertex, lineVectors.colors);
|
||||
else {
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
vertexArray.addBuffer(0, lineBuffers.vertices);
|
||||
vertexArray.addBuffer(1, lineBuffers.colors, 4);
|
||||
|
||||
@ -645,22 +641,26 @@ namespace hex::plugin::visualizers {
|
||||
Vectors<T> vectors;
|
||||
|
||||
vectors.vertices = patternToArray<float>(verticesPattern.get());
|
||||
std::string errorMessage;
|
||||
s_vertexCount = vectors.vertices.size() / 3;
|
||||
if (!validateVector(vectors.vertices, s_vertexCount, 3, std::string("hex.visualizers.pl_visualizer.3d.error_message_positions"_lang), errorMessage))
|
||||
throw std::runtime_error(errorMessage);
|
||||
|
||||
if (s_indexType != IndexType::Undefined) {
|
||||
vectors.indices = patternToArray<T>(indicesPattern.get());
|
||||
s_badIndices.clear();
|
||||
auto indexCount = vectors.indices.size();
|
||||
if (indexCount < 3 || indexCount % 3 != 0) {
|
||||
throw std::runtime_error("Error: IndexCount must be a multiple of 3");
|
||||
throw std::runtime_error(std::string("hex.visualizers.pl_visualizer.3d.error_message_index_count"_lang));
|
||||
}
|
||||
auto booleans = std::views::transform(vectors.indices,isIndexInRange);
|
||||
if (!std::accumulate(std::begin(booleans), std::end(booleans), true, std::logical_and<>())) {
|
||||
std::string errorMessage = "Error: indices must be between 0 and the number of vertices minus one. Invalid indices: ";
|
||||
errorMessage = std::string("hex.visualizers.pl_visualizer.3d.error_message_invalid_indices"_lang);
|
||||
for (auto badIndex : s_badIndices)
|
||||
errorMessage += std::to_string(badIndex) + ", ";
|
||||
errorMessage.pop_back();
|
||||
errorMessage.pop_back();
|
||||
errorMessage += hex::format(" for {} vertices",s_vertexCount);
|
||||
errorMessage += hex::format(std::string("hex.visualizers.pl_visualizer.3d.error_message_for_vertex_count"_lang),s_vertexCount);
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
}
|
||||
@ -677,23 +677,27 @@ namespace hex::plugin::visualizers {
|
||||
bindBuffers(buffers, vertexArray, vectors, s_indexType);
|
||||
} else {
|
||||
LineVectors<T> lineVectors;
|
||||
std::string errorMessage;
|
||||
|
||||
lineVectors.vertices = patternToArray<float>(verticesPattern.get());
|
||||
s_vertexCount = lineVectors.vertices.size() / 3;
|
||||
if (!validateVector(lineVectors.vertices, s_vertexCount, 3, std::string("hex.visualizers.pl_visualizer.3d.error_message_positions"_lang), errorMessage))
|
||||
throw std::runtime_error(errorMessage);
|
||||
|
||||
if (s_indexType != IndexType::Undefined) {
|
||||
lineVectors.indices = patternToArray<T>(indicesPattern.get());
|
||||
auto indexCount = lineVectors.indices.size();
|
||||
if (indexCount < 3 || indexCount % 3 != 0) {
|
||||
throw std::runtime_error("Error: IndexCount must be a multiple of 3");
|
||||
throw std::runtime_error(std::string("hex.visualizers.pl_visualizer.3d.error_message_index_count"_lang));
|
||||
}
|
||||
s_badIndices.clear();
|
||||
if (!std::ranges::all_of(lineVectors.indices,isIndexInRange)) {
|
||||
std::string errorMessage = "Error: indices must be between 0 and the number of vertices minus one. Invalid indices: ";
|
||||
errorMessage = std::string("hex.visualizers.pl_visualizer.3d.error_message_invalid_indices"_lang);
|
||||
for (auto badIndex : s_badIndices)
|
||||
errorMessage += std::to_string(badIndex) + ", ";
|
||||
errorMessage.pop_back();
|
||||
errorMessage.pop_back();
|
||||
errorMessage += hex::format(" for {} vertices",s_vertexCount);
|
||||
errorMessage += hex::format(std::string("hex.visualizers.pl_visualizer.3d.error_message_for_vertex_count"_lang),s_vertexCount);
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user