mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
SettingsHandler: Don't output null bytes
https://bugs.dolphin-emu.org/issues/12019, take two.
This commit is contained in:
parent
5b10f4b71e
commit
5d6f23e424
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "Common/SettingsHandler.h"
|
#include "Common/SettingsHandler.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@ -79,12 +80,10 @@ void SettingsHandler::Decrypt()
|
|||||||
m_key = (m_key >> 31) | (m_key << 1);
|
m_key = (m_key >> 31) | (m_key << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decryption done. Now get rid of all CR in the output.
|
// The decoded data normally uses CRLF line endings, but occasionally
|
||||||
// The decoded file is supposed to contain Windows line endings
|
// (see the comment in WriteLine), lines can be separated by CRLFLF.
|
||||||
// (CR-LF), but sometimes also contains CR-LF-LF endings which
|
// To handle this, we remove every CR and treat LF as the line ending.
|
||||||
// confuse the parsing code, so let's just get rid of all CR
|
// (We ignore empty lines.)
|
||||||
// line endings.
|
|
||||||
|
|
||||||
decoded.erase(std::remove(decoded.begin(), decoded.end(), '\x0d'), decoded.end());
|
decoded.erase(std::remove(decoded.begin(), decoded.end(), '\x0d'), decoded.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,22 +95,33 @@ void SettingsHandler::Reset()
|
|||||||
m_buffer = {};
|
m_buffer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsHandler::AddSetting(std::string_view key, std::string_view value)
|
void SettingsHandler::AddSetting(const std::string& key, const std::string& value)
|
||||||
{
|
{
|
||||||
for (const char& c : key)
|
WriteLine(key + '=' + value + "\r\n");
|
||||||
{
|
|
||||||
WriteByte(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteByte('=');
|
void SettingsHandler::WriteLine(const std::string& str)
|
||||||
|
|
||||||
for (const char& c : value)
|
|
||||||
{
|
{
|
||||||
WriteByte(c);
|
const u32 old_position = m_position;
|
||||||
}
|
const u32 old_key = m_key;
|
||||||
|
|
||||||
WriteByte(13);
|
// Encode and write the line
|
||||||
WriteByte(10);
|
for (char c : str)
|
||||||
|
WriteByte(c);
|
||||||
|
|
||||||
|
// If the encoded data contains a null byte, Nintendo's decoder will stop at that null byte
|
||||||
|
// instead of decoding all the data. To avoid this: If the data we just wrote contains
|
||||||
|
// a null byte, add an LF right before the line to prod the values into being different,
|
||||||
|
// just like Nintendo does. Due to the chosen key, LF itself never encodes into a null byte.
|
||||||
|
const auto begin = m_buffer.cbegin() + old_position;
|
||||||
|
const auto end = m_buffer.cbegin() + m_position;
|
||||||
|
if (std::find(begin, end, 0) != end)
|
||||||
|
{
|
||||||
|
m_key = old_key;
|
||||||
|
m_position = old_position;
|
||||||
|
WriteByte('\n');
|
||||||
|
WriteLine(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsHandler::WriteByte(u8 b)
|
void SettingsHandler::WriteByte(u8 b)
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
SettingsHandler();
|
SettingsHandler();
|
||||||
explicit SettingsHandler(Buffer&& buffer);
|
explicit SettingsHandler(Buffer&& buffer);
|
||||||
|
|
||||||
void AddSetting(std::string_view key, std::string_view value);
|
void AddSetting(const std::string& key, const std::string& value);
|
||||||
|
|
||||||
const Buffer& GetBytes() const;
|
const Buffer& GetBytes() const;
|
||||||
void SetBytes(Buffer&& buffer);
|
void SetBytes(Buffer&& buffer);
|
||||||
@ -39,6 +39,7 @@ public:
|
|||||||
static std::string GenerateSerialNumber();
|
static std::string GenerateSerialNumber();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void WriteLine(const std::string& str);
|
||||||
void WriteByte(u8 b);
|
void WriteByte(u8 b);
|
||||||
|
|
||||||
std::array<u8, SETTINGS_SIZE> m_buffer;
|
std::array<u8, SETTINGS_SIZE> m_buffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user