Skip to content
Snippets Groups Projects
Unverified Commit 97481111 authored by Brian Carrier's avatar Brian Carrier Committed by GitHub
Browse files

Merge pull request #1410 from crayy8/develop

Fix for CT-2917 - fail to get non-ascii registry key names
parents e30c28b2 0cfcd8ac
No related branches found
No related tags found
No related merge requests found
...@@ -85,9 +85,13 @@ namespace Rejistry { ...@@ -85,9 +85,13 @@ namespace Rejistry {
return getASCIIString(0, _byteBuffer->limit()); return getASCIIString(0, _byteBuffer->limit());
} }
/** /**
* Throws exception if offset or length is too large. * Reads data from the registry and returns the data as a string
*/ * as it is represented in the registry, including Null characters.
*
* @param offset: Offset where data begins
* @param length: Number of bytes to read
*/
std::string RegistryByteBuffer::getASCIIString(const uint32_t offset, const uint32_t length) const { std::string RegistryByteBuffer::getASCIIString(const uint32_t offset, const uint32_t length) const {
if (length == 0) { if (length == 0) {
return ""; return "";
...@@ -102,59 +106,66 @@ namespace Rejistry { ...@@ -102,59 +106,66 @@ namespace Rejistry {
return getUTF16String(0, _byteBuffer->limit()); return getUTF16String(0, _byteBuffer->limit());
} }
/**
* Reads data from the registry and returns a wstring of the data
* as it is represented in the registry, including Null characters.
*
* @param offset: Offset where data begins
* @param length: Number of bytes to read
*/
std::wstring RegistryByteBuffer::getUTF16String(const uint32_t offset, const uint32_t length) const { std::wstring RegistryByteBuffer::getUTF16String(const uint32_t offset, const uint32_t length) const {
if (length == 0) { if (length == 0) {
return L""; return L"";
} }
ByteBuffer::ByteArray &data = getData(offset, length);
// If the size of the array is not a multiple of 2 it is
// likely to not be UTF16 encoded. The most common case is that
// the string is simply missing a terminating null so we add it.
if (data.size() % 2 != 0) {
data.push_back('\0');
}
// Find UTF16 null terminator.
uint32_t nullPos = 0;
for (; nullPos < data.size(); nullPos += 2) {
if (data[nullPos] == '\0' && data[nullPos+1] == '\0') {
break;
}
}
// empty string ByteBuffer::ByteArray &data = getData(offset, length);
if (nullPos == 0) { // There are cases where an odd number of bytes are returned which
return L""; // leads to errors during conversion. See CT-2917 test12 for more details.
} if (data.size() % 2 != 0) {
// NULL Pointer not found data.push_back('\0');
else if (nullPos == data.size()) {
// @@@ BC: I'm not sure if this is correct. But, we got exceptions if
// we kept it past the buffer.
// Are these always supposed to be NULL terminated, in which case this is an error?
nullPos = data.size() - 1;
} }
std::wstring result; // Empty value data (single UTF16 null char)
if (data.size() == 2 && data[0] == '\0' && data[1] == '\0') {
return L"";
}
try { // We do this so we can reference the last character in the string
result = conv.from_bytes(reinterpret_cast<const char*>(&data[0]), reinterpret_cast<const char*>(&data[nullPos])); // data.size() -2. if we didn't add a char to the string then returned
} // string would be missing the last character.
catch (std::exception&) data.push_back('\0');
{ data.push_back('\0');
throw RegistryParseException("Error: Failed to convert string");
} // We are unsure how from_bytes() works. Microsofts docs seem to indicate that the second pointer
// should point to the last character which will be included in the conversion.[1] However, another
// reference indicates that the data pointed to by the second pointer will not be included, which is
// what our testing has shown.[2] We previously had the second pointer point to data.size() but there were
// concerns that we were pointing to memory we did not own. As a result, we add a char to the end of every
// string so we can use data.size() - 2 and still get the original string back.
// 1. https://docs.microsoft.com/en-us/cpp/standard-library/wstring-convert-class?view=vs-2017#from_bytes
// 2. http://www.cplusplus.com/reference/locale/wstring_convert/from_bytes/
std::wstring result;
try {
result = conv.from_bytes(reinterpret_cast<const char*>(&data[0]), reinterpret_cast<const char*>(&data[data.size()-2]));
}
catch (std::exception&)
{
throw RegistryParseException("Error: Failed to convert string");
}
return result; return result;
} }
ByteBuffer::ByteArray RegistryByteBuffer::getData() const { ByteBuffer::ByteArray RegistryByteBuffer::getData() const {
return getData(0, _byteBuffer->limit()); return getData(0, _byteBuffer->limit());
} }
/** /**
* Throws exception if offset and length are too large. * Reads data from the registry based off of the given offset and length of data to read.
*/ *
* @param offset: Offset where data begins
* @param length: Number of bytes to read
*/
ByteBuffer::ByteArray RegistryByteBuffer::getData(const uint32_t offset, const uint32_t length) const { ByteBuffer::ByteArray RegistryByteBuffer::getData(const uint32_t offset, const uint32_t length) const {
uint32_t savedPosition = _byteBuffer->position(); uint32_t savedPosition = _byteBuffer->position();
_byteBuffer->position(offset); _byteBuffer->position(offset);
...@@ -169,6 +180,12 @@ namespace Rejistry { ...@@ -169,6 +180,12 @@ namespace Rejistry {
return getStringList(0, _byteBuffer->limit()); return getStringList(0, _byteBuffer->limit());
} }
/**
* Reads data from the registry based off of the given offset and length of data to read.
*
* @param offset: Offset where data begins
* @param length: Number of bytes to read
*/
std::vector<std::wstring> RegistryByteBuffer::getStringList(const uint32_t offset, const uint32_t length) const { std::vector<std::wstring> RegistryByteBuffer::getStringList(const uint32_t offset, const uint32_t length) const {
std::vector<std::wstring> stringList; std::vector<std::wstring> stringList;
ByteBuffer::ByteArray data = getData(offset, length); ByteBuffer::ByteArray data = getData(offset, length);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment