lib/nbt: implement readString NBT helper function
parent
9562ae7be9
commit
b5312aeb58
|
@ -72,7 +72,7 @@ echo "Building tools..."
|
|||
mkdir -pv bin/tools
|
||||
# add compile commands to this array
|
||||
COMPILE_COMMANDS=(
|
||||
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -Lbin/lib -l:nbt.so -o bin/tools/dumpnbt"
|
||||
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -I dependencies/tiny-utf8-4.4.3/include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/tools/dumpnbt"
|
||||
"$CXX_WITH_FLAGS src/tools/hexnet.cpp -Lbin/lib -l:cli.so -l:libsockpp.so -Idependencies/sockpp-0.7.1/include -o bin/tools/hexnet"
|
||||
)
|
||||
for command in ${!COMPILE_COMMANDS[@]}; do
|
||||
|
|
|
@ -37,7 +37,7 @@ echo "Building tests..."
|
|||
|
||||
# add compile commands to this array
|
||||
COMPILE_COMMANDS=(
|
||||
"$CXX_WITH_FLAGS src/test/nbt_helpers.cpp -Lbin/lib -l:nbt.so -o bin/test/nbt_helpers"
|
||||
"$CXX_WITH_FLAGS src/test/nbt_helpers.cpp -Idependencies/tiny-utf8-4.4.3/include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_helpers"
|
||||
"$CXX_WITH_FLAGS src/test/cli_argument_parser.cpp -Lbin/lib -l:cli.so -o bin/test/cli_argument_parser"
|
||||
"$CXX_WITH_FLAGS src/test/javacompat.cpp -Idependencies/tiny-utf8-4.4.3/include -Lbin/lib -l:javacompat.so -o bin/test/javacompat"
|
||||
)
|
||||
|
|
|
@ -81,4 +81,7 @@ namespace ErrorCodes {
|
|||
const uint8_t UNIMPLEMENTED = 254;
|
||||
|
||||
const uint8_t UNKNOWN = 255;
|
||||
|
||||
//mismatched size in java strings
|
||||
const uint8_t MISMATCHEDSIZE = 6;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,13 @@
|
|||
namespace JavaCompat {
|
||||
//FIXME: contrary to what I said, we need to explicitly pass the data
|
||||
// size because files could have been tampered with or corrupted
|
||||
tiny_utf8::string importJavaString(uint8_t data[]) {
|
||||
ErrorOr<tiny_utf8::string> importJavaString(uint8_t data[], uint16_t size) {
|
||||
std::string stdString;
|
||||
uint16_t size = static_cast<uint16_t>(data[0])<<8 | static_cast<uint16_t>(data[1]);
|
||||
uint16_t encodedSize = static_cast<uint16_t>(data[0])<<8 | static_cast<uint16_t>(data[1]);
|
||||
|
||||
if(encodedSize != size){
|
||||
return ErrorOr<tiny_utf8::string>(true, ErrorCodes::MISMATCHEDSIZE);
|
||||
}
|
||||
|
||||
for(uint8_t i=2; i<size+2; i++){
|
||||
if(i != 0){
|
||||
|
@ -45,7 +49,7 @@ namespace JavaCompat {
|
|||
}
|
||||
stdString.push_back((char) data[i]);
|
||||
}
|
||||
return tiny_utf8::string(stdString);
|
||||
return ErrorOr<tiny_utf8::string>(tiny_utf8::string(stdString));
|
||||
}
|
||||
|
||||
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data) {
|
||||
|
@ -54,6 +58,10 @@ namespace JavaCompat {
|
|||
std::vector<uint8_t> output = std::vector<uint8_t>();
|
||||
std::string stdString = data.cpp_str();
|
||||
|
||||
if(stdString.size() > 0xFFFF){
|
||||
return ErrorOr<std::vector<uint8_t>>(true, ErrorCodes::OVERRUN);
|
||||
}
|
||||
|
||||
*size = (uint16_t) stdString.size();
|
||||
|
||||
//placeholder size bytes
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
#include <vector>
|
||||
|
||||
namespace JavaCompat {
|
||||
//FIXME: contrary to what I said, we need to explicitly pass the data
|
||||
// size because files could have been tampered with or corrupted
|
||||
tiny_utf8::string importJavaString(uint8_t data[]);
|
||||
ErrorOr<tiny_utf8::string> importJavaString(uint8_t data[], uint16_t size);
|
||||
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data);
|
||||
}
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
#include <bit>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <tinyutf8/tinyutf8.h>
|
||||
|
||||
#include "nbt.h++"
|
||||
#include "error.h++"
|
||||
#include "javacompat.h++"
|
||||
|
||||
|
||||
#include "../../.endianness"
|
||||
#ifdef FOSSVG_ENDIAN_BIG_WORD
|
||||
|
@ -148,10 +151,17 @@ namespace NBT {
|
|||
// Maybe use a struct that holds decoded (de-Java-fied) string
|
||||
// data, decoded size, and original size? Original size is needed
|
||||
// so the parser knows where to continue.
|
||||
//ErrorOr<> readString(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
||||
//TODO: implement
|
||||
// return ErrorOr<>("");
|
||||
//}
|
||||
ErrorOr<tiny_utf8::string> readString(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
||||
if(dataSize > 0xFFFF){
|
||||
return ErrorOr<tiny_utf8::string>(true, ErrorCodes::OVERRUN);
|
||||
}
|
||||
|
||||
ErrorOr<tiny_utf8::string> output = JavaCompat::importJavaString(data+currentPosition, (uint16_t) dataSize);
|
||||
if(output.isError){
|
||||
return ErrorOr<tiny_utf8::string>(true, output.errorCode);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
ErrorOr<std::vector<int32_t>> readInt32Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
|
||||
// get size prefix
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include "error.h++"
|
||||
#include <tinyutf8/tinyutf8.h>
|
||||
|
||||
namespace NBT {
|
||||
namespace helper {
|
||||
|
@ -52,7 +53,7 @@ namespace NBT {
|
|||
// floating point number
|
||||
ErrorOr<double> readFloat64(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<std::vector<int8_t>> readInt8Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
//ErrorOr<> readString(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<tiny_utf8::string> readString(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<std::vector<int32_t>> readInt32Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
ErrorOr<std::vector<int64_t>> readInt64Array(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ int main(){
|
|||
return 2;
|
||||
}
|
||||
|
||||
tiny_utf8::string importedString = JavaCompat::importJavaString(reinterpret_cast<uint8_t*>(javaStdString.data()));
|
||||
tiny_utf8::string importedString = JavaCompat::importJavaString(reinterpret_cast<uint8_t*>(javaStdString.data()), 0x75).value;
|
||||
|
||||
std::streampos normalSize;
|
||||
std::string normalStdString;
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
#include "assert.h++"
|
||||
|
||||
#include "../lib/nbt.h++"
|
||||
#include "../lib/error.h++"
|
||||
#include "../lib/javacompat.h++"
|
||||
|
||||
int main(){
|
||||
std::cout << "################################################################################" << std::endl;
|
||||
|
@ -442,5 +444,56 @@ int main(){
|
|||
|
||||
std::cout << "Passed writeInt64 NBT helper test" << std::endl;
|
||||
|
||||
//readString test
|
||||
char* nextChar = new char;
|
||||
|
||||
//reading data from the java modified utf8 file
|
||||
std::streampos javaSize;
|
||||
std::string javaStdString;
|
||||
const char* javaFilePath = "./resources/unicode_data/java-style_unicode";
|
||||
std::ifstream javaFile(javaFilePath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if(javaFile.is_open()){
|
||||
javaSize = javaFile.tellg();
|
||||
javaFile.seekg(0, std::ios::beg);
|
||||
|
||||
for (int i=0; i<javaSize; i++) {
|
||||
javaFile.read(nextChar, 1);
|
||||
javaStdString.push_back(*nextChar);
|
||||
}
|
||||
|
||||
javaFile.close();
|
||||
} else {
|
||||
std::cerr << "Failed to open file: " << javaFilePath << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
//reading data from the normal utf8 file
|
||||
std::streampos normalSize;
|
||||
std::string normalStdString;
|
||||
const char* normalFilePath = "./resources/unicode_data/normal_utf-8";
|
||||
std::ifstream normalFile(normalFilePath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if(normalFile.is_open()){
|
||||
normalSize = normalFile.tellg();
|
||||
normalFile.seekg(0, std::ios::beg);
|
||||
|
||||
for (int i=0; i<normalSize; i++) {
|
||||
normalFile.read(nextChar, 1);
|
||||
normalStdString.push_back(*nextChar);
|
||||
}
|
||||
|
||||
normalFile.close();
|
||||
} else {
|
||||
std::cerr << "Failed to open file: " << normalFilePath << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
tiny_utf8::string normalString = tiny_utf8::string(normalStdString);
|
||||
|
||||
ASSERT(normalString == NBT::helper::readString(reinterpret_cast<uint8_t*>(javaStdString.data()), 0x75, 0).value)
|
||||
ASSERT(NBT::helper::readString(reinterpret_cast<uint8_t*>(javaStdString.data()), 0xFFFFF, 0).errorCode == ErrorCodes::OVERRUN);
|
||||
ASSERT(NBT::helper::readString(reinterpret_cast<uint8_t*>(javaStdString.data()), 0xF, 0).errorCode == ErrorCodes::MISMATCHEDSIZE);
|
||||
std::cout << "Passed readString NBT helper test." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue