Compare commits

..

No commits in common. "b63c1398a64c5162dbdda64a26d6fa6e66535779" and "c0b838d1f2f5b09f0665920b8c2d3ea04e04b958" have entirely different histories.

10 changed files with 77 additions and 192 deletions

View File

@ -33,7 +33,7 @@ fi
# `.cpp` files in src/lib will be automatically picked up and compiled into
# dynamically linked libraries.
echo ">>> Building libs..."
echo "Building libs..."
create_directory bin/lib
for lib in $(find ./src/lib -name "*.cpp"); do
COMPILE_COMMAND="$CXX_WITH_FLAGS -I ./include -fPIC -shared -o $(sed -e 's/^.\/src/.\/bin/;s/cpp$/so/' <<< $lib) $lib"
@ -55,7 +55,7 @@ wait
# How to run a tool: specify the library path to use for the dynamic linker
# when running a program
# Example: LD_LIBRARY_PATH=bin/lib bin/tools/dumpnbt
echo ">>> Building tools..."
echo "Building tools..."
create_directory bin/tools
# add compile commands to this array
COMPILE_COMMANDS=(

View File

@ -15,8 +15,6 @@
# version 3 along with this program.
# If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
echo ">>> Cleaning build files..."
source scripts/lib.sh
remove ./bin

View File

@ -17,7 +17,7 @@
source scripts/lib.sh
echo ">>> Checking download cache for unneeded or corrupted files..."
echo "Checking download cache for unneeded or corrupted files..."
for file in $(ls .download_cache); do
#TODO: remove if unknown shasum
if grep $file scripts/setup_project.sh >/dev/null 2>&1; then
@ -32,8 +32,7 @@ for file in $(ls .download_cache); do
rm ".download_cache/$file"
fi
done
echo "
>>> Cleaning dependencies..."
echo ""
remove ./dependencies
create_directory ./dependencies

View File

@ -72,7 +72,9 @@ function download {
fi
}
echo "Cleaning build files..."
scripts/clean.sh
echo "Cleaning dependencies..."
scripts/clean_dependencies.sh
set -e # failures are not acceptable here
@ -80,21 +82,20 @@ create_directory dependencies/tmp
download https://github.com/DuffsDevice/tiny-utf8/archive/refs/tags/v4.4.3.tar.gz dependencies/tmp/tiny-utf8.tar.gz 8e3f61651909c9f3105d3501932a96aa65733127fb6e7cf94cb1b0a2dff42c8f
download https://github.com/fpagliughi/sockpp/archive/refs/tags/v0.7.1.tar.gz dependencies/tmp/sockpp.tar.gz 2e023528bebbd2ac083fc91fbe6d5c4158c3336bedbcff48f594f3b28f53b940
echo -n ">>> Extracting tiny-utf8... "
echo -n "Extracting tiny-utf8... "
gzip -d dependencies/tmp/tiny-utf8.tar.gz
tar -xf dependencies/tmp/tiny-utf8.tar -C dependencies
echo "done"
echo "done."
echo -n ">>> Extracting sockpp... "
echo -n "Extracting sockpp... "
gzip -d dependencies/tmp/sockpp.tar.gz
tar -xf dependencies/tmp/sockpp.tar -C dependencies
echo "done"
echo ">>> Building sockpp... "
echo "done."
echo -n "Building sockpp... "
pushd dependencies/sockpp-0.7.1/ >/dev/null 2>&1
cmake -Bbuild .
cmake --build build
popd >/dev/null 2>&1
echo "done."
echo ">>> Cleaning up..."
remove dependencies/tmp

View File

@ -25,11 +25,9 @@ else
fi
echo "$LD_LIBRARY_PATH"
echo ">>> Cleaning tests..."
remove bin/test
create_directory bin/test
echo ">>> Building tests..."
echo "Building tests..."
# add compile commands to this array
COMPILE_COMMANDS=(
@ -38,7 +36,6 @@ COMPILE_COMMANDS=(
"$CXX_WITH_FLAGS src/test/javacompat.cpp -I./include -Lbin/lib -l:javacompat.so -o bin/test/javacompat"
"$CXX_WITH_FLAGS src/test/nbt_write_string_failure_mode.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_write_string_failure_mode"
"$CXX_WITH_FLAGS src/test/nbt_tags.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_tags"
"$CXX_WITH_FLAGS src/test/nbt_size_helpers.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_size_helpers"
)
for command in ${!COMPILE_COMMANDS[@]}; do
echo "${COMPILE_COMMANDS[command]}"
@ -48,15 +45,9 @@ done
wait
echo ">>> Running tests..."
echo "Running tests..."
# explicitly allow commands to fail at this stage
set +e
for test in $(ls bin/test); do
bin/test/$test
done
for test in $(ls scripts/test); do
scripts/test/$test
done

View File

@ -1,23 +0,0 @@
#!/usr/bin/env bash
# Copyright 2022, FOSS-VG Developers and Contributers
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# version 3 along with this program.
# If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
echo "################################################################################
Testing hexnet
################################################################################"
echo "Test not yet implemented."
#TODO: implement unit test after merging back with master

View File

@ -375,11 +375,9 @@ namespace NBT {
// one that is applicable to the situation (for example replace
// OUT_OF_RANGE with OVERRUN where appropriate)
//
// The total size in bytes
//
// Does not work for compound tags and lists. This is an intended
// feature as compound tags and lists need to be dealt with
// separately to avoid unnecessarily long and complex code.
// separately to avoid unnecessarily complex code.
//
// Regardinng lists specifically: The size of some lists can can
// be determined easily by looking at the contained data type and
@ -388,7 +386,7 @@ namespace NBT {
// contents requires special attention anyway due the tag headers
// of contained tags being absent so they may as well get their
// own function for this as well.
ErrorOr<uint64_t> totalTagSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
ErrorOr<uint64_t> nextTagTotalSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition) {
uint8_t nextTag;
if (dataSize <= currentPosition) {
return ErrorOr<uint64_t>(true, ErrorCodes::OVERRUN);
@ -399,53 +397,81 @@ namespace NBT {
if (nextTag == TagType::COMPOUND || nextTag == TagType::LIST) return ErrorOr<uint64_t>(false, ErrorCodes::NOT_YET_KNOWN);
// deal with end tag before trying to access the name
if (nextTag == TagType::END) return ErrorOr<uint64_t>(1);
// get name size
ErrorOr<int16_t> nameSize = helper::readInt16(data, dataSize, currentPosition+1);
if (nameSize.isError) {
return ErrorOr<uint64_t>(true, nameSize.errorCode);
}
// add type byte and name size bytes
uint64_t prefixSize = (uint64_t) nameSize.value + 3;
switch (nextTag) {
case TagType::INT8:
return ErrorOr<uint64_t>(prefixSize+1);
// type byte + name size + data byte -> 4 bytes
return ErrorOr<uint64_t>((uint64_t) nameSize.value+4);
case TagType::INT16:
return ErrorOr<uint64_t>(prefixSize+2);
// type byte + name size + 2 data bytes -> 5 bytes
return ErrorOr<uint64_t>((uint64_t) nameSize.value+5);
case TagType::INT32:
return ErrorOr<uint64_t>(prefixSize+4);
// type byte + name size + 4 data bytes -> 7 bytes
return ErrorOr<uint64_t>((uint64_t) nameSize.value+7);
case TagType::INT64:
return ErrorOr<uint64_t>(prefixSize+8);
// type byte + name size + 8 data bytes -> 11 bytes
return ErrorOr<uint64_t>((uint64_t) nameSize.value+11);
case TagType::FLOAT:
return ErrorOr<uint64_t>(prefixSize+4);
// type byte + name size + 4 data bytes -> 7 bytes
return ErrorOr<uint64_t>((uint64_t) nameSize.value+7);
case TagType::DOUBLE:
return ErrorOr<uint64_t>(prefixSize+8);
// type byte + name size + 8 data bytes -> 11 bytes
return ErrorOr<uint64_t>((uint64_t) nameSize.value+11);
case TagType::INT8_ARRAY: {
ErrorOr<int32_t> arrayLength = helper::readInt32(data, dataSize, currentPosition+prefixSize);
if (arrayLength.isError) {
return ErrorOr<uint64_t>(true, arrayLength.errorCode);
// type byte + name size + 4 size bytes -> 7 bytes
uint64_t totalSize = (uint64_t) nameSize.value+7;
// add size of actual data (1 byte per entry)
ErrorOr<int32_t> arraySize = helper::readInt32(data, dataSize, currentPosition+totalSize);
if (arraySize.isError) {
return ErrorOr<uint64_t>(true, arraySize.errorCode);
}
return ErrorOr<uint64_t>((uint64_t) arrayLength.value + prefixSize + 4);
totalSize += (uint64_t) arraySize.value;
return ErrorOr<uint64_t>(totalSize);
}
case TagType::STRING: {
ErrorOr<int16_t> stringSize = helper::readInt16(data, dataSize, currentPosition+prefixSize);
// type byte + name size + 2 size bytes -> 5 bytes
uint64_t totalSize = (uint64_t) nameSize.value+5;
// add size of actual data
ErrorOr<int16_t> stringSize = helper::readInt16(data, dataSize, currentPosition+totalSize);
if (stringSize.isError) {
return ErrorOr<uint64_t>(true, stringSize.errorCode);
}
return ErrorOr<uint64_t>((uint64_t) stringSize.value + prefixSize + 2);
totalSize += (uint64_t) stringSize.value;
return ErrorOr<uint64_t>(totalSize);
}
case TagType::INT32_ARRAY: {
ErrorOr<int32_t> arrayLength = helper::readInt32(data, dataSize, currentPosition+prefixSize);
if (arrayLength.isError) {
return ErrorOr<uint64_t>(true, arrayLength.errorCode);
// type byte + name size + 4 size bytes -> 7 bytes
uint64_t totalSize = (uint64_t) nameSize.value+7;
// add size of actual data (4 bytes per entry)
ErrorOr<int16_t> arraySize = helper::readInt16(data, dataSize, currentPosition+totalSize);
if (arraySize.isError) {
return ErrorOr<uint64_t>(true, arraySize.errorCode);
}
return ErrorOr<uint64_t>((uint64_t) arrayLength.value*4 + prefixSize + 4);
totalSize += (uint64_t) arraySize.value*4;
return ErrorOr<uint64_t>(totalSize);
}
case TagType::INT64_ARRAY: {
ErrorOr<int32_t> arrayLength = helper::readInt32(data, dataSize, currentPosition+prefixSize);
if (arrayLength.isError) {
return ErrorOr<uint64_t>(true, arrayLength.errorCode);
// type byte + name size + 4 size bytes -> 7 bytes
uint64_t totalSize = (uint64_t) nameSize.value+7;
// add size of actual data (8 bytes per entry)
ErrorOr<int16_t> arraySize = helper::readInt16(data, dataSize, currentPosition+totalSize);
if (arraySize.isError) {
return ErrorOr<uint64_t>(true, arraySize.errorCode);
}
return ErrorOr<uint64_t>((uint64_t) arrayLength.value*8 + prefixSize + 4);
totalSize += (uint64_t) arraySize.value*8;
return ErrorOr<uint64_t>(totalSize);
}
// unknown tag or parsing error
default:
@ -453,67 +479,22 @@ namespace NBT {
}
}
//FIXME: instead of blindly passing the error code upwards, choose
// one that is applicable to the situation (for example replace
// OUT_OF_RANGE with OVERRUN where appropriate)
//
// Length is the number of stored elements, not to be confused with size
// which is the size in bytes.
ErrorOr<int32_t> containedDataLength(uint8_t data[], uint64_t dataSize, uint64_t currentPosition){
ErrorOr<uint32_t> nextTagDataSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition){
uint8_t nextTag;
if (dataSize <= currentPosition) {
return ErrorOr<int32_t>(true, ErrorCodes::OVERRUN);
return ErrorOr<uint32_t>(true, ErrorCodes::OVERRUN);
} else {
nextTag = data[currentPosition];
}
// deal with compound tags separately
if (nextTag == TagType::COMPOUND) {
return ErrorOr<int32_t>(true, ErrorCodes::NOT_YET_KNOWN);
}
if (nextTag == TagType::COMPOUND) return ErrorOr<uint32_t>(true, ErrorCodes::NOT_YET_KNOWN);
// deal with end tag before trying to access the name
if (nextTag == TagType::END) {
return ErrorOr<int32_t>(0);
}
// tags that only ever hold one value
if (nextTag == TagType::INT8 || nextTag == TagType::INT16 || nextTag == TagType::INT32 || nextTag == TagType::INT64 || nextTag == TagType::FLOAT || nextTag == TagType::DOUBLE) {
return ErrorOr<int32_t>(1);
}
ErrorOr<int16_t> nameSize = helper::readInt16(data, dataSize, currentPosition+1);
if (nameSize.isError) {
return ErrorOr<int32_t>(true, nameSize.errorCode);
}
// add type byte and name size bytes
uint64_t prefixSize = (uint64_t) nameSize.value + 3;
switch (nextTag) {
case TagType::INT8_ARRAY: {
return helper::readInt32(data, dataSize, currentPosition+prefixSize);
}
case TagType::STRING: {
ErrorOr<int16_t> stringSize = helper::readInt16(data, dataSize, currentPosition+prefixSize);
if (stringSize.isError) {
return ErrorOr<int32_t>(true, stringSize.errorCode);
}
return ErrorOr<int32_t>((int32_t) stringSize.value);
}
case TagType::LIST: {
// add an additional byte for the contained data type
return helper::readInt32(data, dataSize, currentPosition+prefixSize+1);
}
case TagType::INT32_ARRAY: {
return helper::readInt32(data, dataSize, currentPosition+prefixSize);
}
case TagType::INT64_ARRAY: {
return helper::readInt32(data, dataSize, currentPosition+prefixSize);
}
default:
// unknown tag or parsing error
return ErrorOr<int32_t>(true, ErrorCodes::UNKNOWN);
}
if (nextTag == TagType::END) return 0;
//TODO: implement for all the remaining types
// unknown tag or parsing error
return ErrorOr<uint32_t>(true, ErrorCodes::UNKNOWN);
}
}

View File

@ -67,8 +67,8 @@ namespace NBT {
void writeInt64Array(std::vector<uint8_t>* destination, std::vector<int64_t> data);
void writeInt64Array(std::vector<uint8_t>* destination, int64_t data[], uint32_t dataSize);
ErrorOr<uint64_t> totalTagSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
ErrorOr<int32_t> containedDataLength(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
ErrorOr<uint64_t> nextTagTotalSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
ErrorOr<uint32_t> nextTagDataSize(uint8_t data[], uint64_t dataSize, uint64_t currentPosition);
}
namespace TagType {

View File

@ -26,7 +26,7 @@
int main(){
std::cout << "################################################################################" << std::endl;
std::cout << "NBT read/write helper tests" << std::endl;
std::cout << "NBT helper tests" << std::endl;
std::cout << "################################################################################" << std::endl;
// used for all integer tests

View File

@ -1,62 +0,0 @@
// Copyright 2022, FOSS-VG Developers and Contributers
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// version 3 along with this program.
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
#include <iostream>
#include <cstdint>
#include "assert.hpp"
#include "../lib/nbt.hpp"
#include "../lib/error.hpp"
int main() {
std::cout
<< "################################################################################\n"
<< "NBT size helper tests\n"
<< "################################################################################"
<< std::endl;
// end tag #########################################################
// const uint8_t END = 0;
uint8_t endTestData[] = {
0x00, 0x0a, 0x00, 0x11, 0x63, 0x6f, 0x6d, 0x70,
0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x6c, 0x65, 0x76,
0x65, 0x6c, 0x5f, 0x32, 0x62, 0x05, 0x00, 0x03,
0x33, 0x30, 0x30, 0x6e, 0x75, 0x6f, 0x70, 0x09,
0x00, 0x03
};
ErrorOr<uint64_t> totalSize = NBT::helper::totalTagSize(endTestData, 34, 0);
ErrorOr<int32_t> dataLength = NBT::helper::containedDataLength(endTestData, 34, 0);
ASSERT(!totalSize.isError);
ASSERT(totalSize.value == 1);
ASSERT(!dataLength.isError);
ASSERT(dataLength.value == 0);
//const uint8_t INT8 = 1;
//const uint8_t INT16 = 2;
//const uint8_t INT32 = 3;
//const uint8_t INT64 = 4;
//const uint8_t FLOAT = 5;
//const uint8_t DOUBLE = 6;
//const uint8_t INT8_ARRAY = 7;
//const uint8_t STRING = 8;
//const uint8_t LIST = 9;
//const uint8_t COMPOUND = 10;
//const uint8_t INT32_ARRAY= 11;
//const uint8_t INT64_ARRAY= 12;
return 0;
}