Merge pull request #22062 from hrydgard/fix-data-audit-bugs

Common audit: Fix /data bugs
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-08-10 00:04:08 +02:00
commit cf08144ab8
18 files changed
+123 -70

No files matched your search

+5 -1
View File
@@ -188,6 +188,10 @@ public:
// If return value is negative, one wasn't found.
int next_crlf_offset() {
// A trailing '\r' with no '\n' after it yet (e.g. right at a TCP fragmentation
// boundary) is a normal "not found yet", not an error - don't peek() past the
// data we actually have.
const size_t totalSize = size();
int offset = 0;
Block *b = head_;
do {
@@ -195,7 +199,7 @@ public:
for (int i = 0; i < remain; i++) {
if (b->data[b->head + i] == '\r') {
// Use peek to avoid handling edge cases.
if (peek(offset + i + 1) == '\n') {
if ((size_t)(offset + i + 1) < totalSize && peek(offset + i + 1) == '\n') {
return offset + i;
}
}
+6 -2
View File
@@ -89,9 +89,13 @@ public:
// Limited functionality for inserts and similar, add as needed.
T &insert(T *iter) {
int pos = iter - data_;
// Capture the old size before ExtendByOne() bumps size_ - the move should only
// cover the elements that actually existed before this insert, not size_ + 1
// worth (which would read/write one element past the valid old range).
int oldSize = (int)size_;
ExtendByOne();
if (pos + 1 < (int)size_) {
memmove(data_ + pos + 1, data_ + pos, (size_ - pos) * sizeof(T));
if (pos < oldSize) {
memmove(data_ + pos + 1, data_ + pos, (oldSize - pos) * sizeof(T));
}
return data_[pos];
}
+5
View File
@@ -43,6 +43,11 @@ struct ShiftJIS {
}
// Okay, if we didn't return, it's time for the second byte (the cell.)
if (c_[index_] == 0) {
// Truncated sequence right at the end of the string - don't consume the
// terminator, or index_ would end up one past it (OOB on the next call).
return INVALID;
}
j = (uint8_t)c_[index_++];
// Not a valid second byte.
if (j < 0x40 || j == 0x7F || j >= 0xFD) {
+18 -3
View File
@@ -106,7 +106,12 @@ bool JsonGet::getStringVector(std::vector<std::string> *vec) const {
}
double JsonGet::getFloat(const char *child_name) const {
return get(child_name, JSON_NUMBER)->value.toNumber();
const JsonNode *val = get(child_name, JSON_NUMBER);
if (!val) {
ERROR_LOG(Log::IO, "Number '%s' missing from node", child_name);
return 0.0;
}
return val->value.toNumber();
}
double JsonGet::getFloat(const char *child_name, double default_value) const {
@@ -117,7 +122,12 @@ double JsonGet::getFloat(const char *child_name, double default_value) const {
}
int JsonGet::getInt(const char *child_name) const {
return (int)get(child_name, JSON_NUMBER)->value.toNumber();
const JsonNode *val = get(child_name, JSON_NUMBER);
if (!val) {
ERROR_LOG(Log::IO, "Number '%s' missing from node", child_name);
return 0;
}
return (int)val->value.toNumber();
}
int JsonGet::getInt(const char *child_name, int default_value) const {
@@ -128,7 +138,12 @@ int JsonGet::getInt(const char *child_name, int default_value) const {
}
bool JsonGet::getBool(const char *child_name) const {
return get(child_name)->value.getTag() == JSON_TRUE;
const JsonNode *val = get(child_name);
if (!val) {
ERROR_LOG(Log::IO, "Value '%s' missing from node", child_name);
return false;
}
return val->value.getTag() == JSON_TRUE;
}
bool JsonGet::getBoolOr(const char *child_name, bool default_value) const {
+13 -1
View File
@@ -90,7 +90,19 @@ void RIFFReader::Ascend() {
}
void RIFFReader::ReadData(void *what, int count) {
memcpy(what, data_ + pos_, count);
if (count > 0) {
int available = pos_ < fileSize_ ? fileSize_ - pos_ : 0;
int toRead = count < available ? count : available;
if (toRead > 0) {
memcpy(what, data_ + pos_, toRead);
}
if (toRead < count) {
// Truncated/corrupt file - don't read past the buffer. Zero the rest so
// callers don't read uninitialized data.
ERROR_LOG(Log::IO, "RIFFReader::ReadData: wanted %d bytes but only %d available", count, toRead);
memset((uint8_t *)what + toRead, 0, count - toRead);
}
}
pos_ += count;
count &= 3;
if (count) {
+2 -2
View File
@@ -43,7 +43,7 @@ RenderPassType MergeRPTypes(RenderPassType a, RenderPassType b) {
}
void VulkanQueueRunner::CreateDeviceObjects() {
INFO_LOG(Log::G3D, "VulkanQueueRunner::CreateDeviceObjects");
DEBUG_LOG(Log::G3D, "VulkanQueueRunner::CreateDeviceObjects");
RPKey key{
VKRRenderPassLoadAction::CLEAR, VKRRenderPassLoadAction::CLEAR, VKRRenderPassLoadAction::CLEAR,
@@ -67,7 +67,7 @@ void VulkanQueueRunner::CreateDeviceObjects() {
}
void VulkanQueueRunner::DestroyDeviceObjects() {
INFO_LOG(Log::G3D, "VulkanQueueRunner::DestroyDeviceObjects");
DEBUG_LOG(Log::G3D, "VulkanQueueRunner::DestroyDeviceObjects");
syncReadback_.Destroy(vulkan_);
+1 -1
View File
@@ -141,7 +141,7 @@ bool Connection::Connect(int maxTries, double timeout, bool *cancelConnect) {
if (!unreachable) {
ERROR_LOG(Log::HTTP, "connect(%d) call to %s failed (%d: %s)", sock, addrStr, errorCode, errorString.c_str());
} else {
INFO_LOG(Log::HTTP, "connect(%d): Ignoring unreachable resolved address %s", sock, addrStr);
VERBOSE_LOG(Log::HTTP, "connect(%d): Ignoring unreachable resolved address %s", sock, addrStr);
}
closesocket(sock);
continue;
+2 -2
View File
@@ -292,13 +292,13 @@ void TextDrawerSDL::SetOrCreateFont(const FontStyle &style) {
uint8_t *fileData = nullptr;
std::string useFont = GetFilenameForFontStyle(style) + ".ttf";
const int ptSize = static_cast<int>(style.sizePts / dpiScale_ * 1.25f);
INFO_LOG(Log::G3D, "Loading SDL font '%s' from VFS at size %d pts", useFont.c_str(), ptSize);
DEBUG_LOG(Log::G3D, "Loading SDL font '%s' from VFS at size %d pts", useFont.c_str(), ptSize);
size_t fileSz;
fileData = g_VFS.ReadFile(useFont.c_str(), &fileSz);
if (fileData) {
SDL_IOStream *rw = SDL_IOFromConstMem(fileData, fileSz);
INFO_LOG(Log::G3D, "Opened font from RW: '%p' '%d'", fileData, (int)fileSz);
DEBUG_LOG(Log::G3D, "Opened font from RW: '%p' '%d'", fileData, (int)fileSz);
font = TTF_OpenFontIO(rw, true, static_cast<float>(ptSize));
if (!font) {
ERROR_LOG(Log::G3D, "Failed to load font from asset file: '%s'", useFont.c_str());