Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions src/common/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* SPDX-License-Identifier: MIT
*
* Copyright (c) 2003 Thomas Combeleran
* Copyright (c) 2025 Donovan Watteau
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -27,6 +28,7 @@
#include "common/io.hpp"
#include "common/toolbox.hpp"

#include <cstddef>
#include <cstring>

#include <algorithm>
Expand Down Expand Up @@ -765,10 +767,49 @@ bool FilePart::eof()

void FilePart::_xorBuffer(char *buffer, byte xorKey, std::streamsize n)
{
uint32 xorKeyd;
uint32 tmp;
std::streamsize alignBytes;
std::streamsize i;

// Nothing to do, if it's an empty key
if (xorKey == 0)
return;

for (std::streamsize i = 0; i < n; i++)
i = 0;

// Don't bother setting up an optimization if there are just
// a few bytes to copy.
if (n >= 16)
{
// If the buffer isn't already 4-byte aligned, process all the
// bytes, before hitting a 4-byte boundary
alignBytes = static_cast<std::streamsize>((-reinterpret_cast<ptrdiff_t>(buffer)) & (sizeof(uint32) - 1));
if (alignBytes > 0 && alignBytes <= n)
{
for ( ; i < alignBytes; ++i)
buffer[i] ^= xorKey;

// If everything has been processed while aligning, it
// means we're done
if (i == n)
return;
}

// Now that the buffer is aligned, continue working on 4-byte
// values at once, for better performance. If there are some
// bytes left, they will be handled in the last run below.
xorKeyd = xorKey | (uint32)xorKey << 8 | (uint32)xorKey << 16 | (uint32)xorKey << 24;
for ( ; i + 4 <= n; i += 4)
{
memcpy(&tmp, buffer + i, sizeof tmp);
tmp ^= xorKeyd;
memcpy(buffer + i, &tmp, sizeof tmp);
}
}

// Process any remaining bytes
for ( ; i < n; ++i)
buffer[i] ^= xorKey;
}

Expand Down Expand Up @@ -859,7 +900,8 @@ FilePart &FilePart::write(const char *s, std::streamsize n)
{
xored = new char[n];
std::memcpy(xored, s, n);
FilePart::_xorBuffer(xored, _xorKey, n);
if (_xorKey != 0)
FilePart::_xorBuffer(xored, _xorKey, n);
_file->write(xored, n);
}
catch (...)
Expand Down