Commit Graph

245 Commits (01e5f5eaac6838bbbf20a021134c4a52f83b12b3)

Author SHA1 Message Date
Shwoomple 9610f4a4a2 lib/file: implement open function 2022-09-28 08:21:39 +05:30
BodgeMaster 434c976cc5 lib/nbt: Continue implementing in-memory NBT tag data types
This is still all unvalidated work.
For all I know it might cause your computer to burst into flames,
grow an arm and a leg and an eye, and attack you with a sword.
But probably, it will just not work and I will realize that sleepy
past me was a fucking idiot (as always).
2022-09-28 03:43:54 +02:00
BodgeMaster 47fd1f8970 test/nbt_read_write_helpers: Change unnecessarily long string to be just one above the allowed size 2022-09-26 23:53:53 +02:00
BodgeMaster 10b1d9fa0c lib/nbt: Start implementing NBT data types, make NBT::Helper::writeString() return an error instead of aborting the program
The former is finally some progress on getting NBT going,
though at this point it is all unvalidated work.
For all I know it might cause your computer to burst into flames,
grow an arm and a leg and an eye, and attack you with a sword.
But probably, it won’t do that and instead start working after I
have debugged it so much that I wish I could attack my PC with a sword.

The latter is the implementation of a change I prepared in a previous commit
when i added ErrorOrVoid.
2022-09-26 03:11:44 +02:00
BodgeMaster 398321e415 test/nbt*: Replace NBT::helper with NBT::Helper
Yes, I forgot to run the test suite before committing.
This is why we need CI.
2022-09-19 11:47:29 +02:00
BodgeMaster 53878c3e2b lib/nbt: Start implementing the in-memory data structure for NBT 2022-09-15 06:06:47 +02:00
BodgeMaster ad291ee77d lib/nbt: Capitalize NBT::Helper because I feel like it 2022-09-15 02:00:07 +02:00
BodgeMaster aab91a2523 lib/nbt: Fix NBT::validateRawNBTData() and NBT::validateRawListContents closing #52 and #53 2022-09-11 09:14:32 +02:00
BodgeMaster 58b1199e38 lib/javacompat: Fixed JavaCompat::importJavaString() hanging when trying to import long strings
This was caused by an integer overflow due to using a too small data type in a counter variable.
2022-09-11 09:08:08 +02:00
Shwoomple 48f8a7dcf2 tools/hexnet: start implementing console input 2022-08-30 00:52:06 +05:30
BodgeMaster 209d0828b4 tools/hexnet: un-comment problematic sections 2022-08-29 21:06:54 +02:00
BodgeMaster b4d4ce77b2 tools/dumpnbt: better variable name and exit when data is invalid 2022-08-29 21:02:36 +02:00
BodgeMaster ee5048331c tools/dumpnbt: start implementing a preliminary version
for use until the full NBT library is in place...
2022-08-28 13:59:31 +02:00
BodgeMaster 629c999336 lib/nbt: Return correct error code from read functions (fixes #17) 2022-08-27 22:35:10 +02:00
BodgeMaster cdd17045d1 test/nbt_read_write_helpers: add more tests according to issue #43 2022-08-27 20:10:29 +02:00
BodgeMaster bb40f6553e tools/hexnet: comment sections out temporarily to get rid of compile errors
Doesn’t compile on Void x86_32 glibc. This will need to be investigated.
I just wanted to get rid of the errors while working on other issues.

Compile command:
ccache g++ -std=c++20 -Wall -Wextra src/tools/hexnet.cpp -I./include -Lbin/lib -l:cli.so -l:libsockpp.so -o bin/tools/hexnet
2022-08-27 11:50:36 +02:00
BodgeMaster a9759e3bc2 lib/file: Clarify what the functions do, take cursor position into account for cut functions and add missing cut function 2022-08-24 01:38:44 +02:00
BodgeMaster ab1164557d lib/file: Write header
I hope I didn’t forget anything. Not exactly capable of thinking rn.
2022-08-24 01:27:34 +02:00
BodgeMaster 1b8819ffe5 lib/error: Add ErrorOrVoid
This allows for error propagation on functions that would otherwise
not return anything.
2022-08-24 01:21:38 +02:00
BodgeMaster 4934a78aaa lib/error: Move definitions of constructors of ErrorOr<> inside class definition. 2022-08-24 01:19:59 +02:00
BodgeMaster 5272636cb8 test/nbt_read_write_helpers: fix unit tests for readString() 2022-08-15 13:30:53 +02:00
BodgeMaster 91d16ea451 test/javacompat: add test for mismatched size 2022-08-15 12:24:03 +02:00
BodgeMaster a1fc0ce4b4 lib/nbt: Fix a possible buffer overflow in readString() 2022-08-15 12:02:58 +02:00
Shwoomple ca7b121c4d tools/hexnet: Implement udp partially. 2022-08-15 15:07:33 +05:30
BodgeMaster 25bec4c587 lib/nbt: Validator: Fix bytes not being added up correctly in multiple places 2022-08-15 10:51:50 +02:00
BodgeMaster 589cf1ddaf lib/nbt: NBT validator: Fix wrong function declaration in the header, fix not using the currentPosition variable when accessing data 2022-08-15 09:53:06 +02:00
BodgeMaster 884a5239c6 lib/nbt: fix a bug in NBT::helper::readString() which caused it to asuume that dataSize is the size of the string 2022-08-15 09:51:46 +02:00
BodgeMaster 9190cad80d lib/nbt: finish implementation of validateRawNBTData() and fix a critical macro-induced bug
I did a `#define return` and then tried to `if () return;` everywhere...
2022-08-15 08:50:07 +02:00
BodgeMaster a862590370 lib/nbt: Start implementing the NBT validator
In theory, this is it. It’s just missing the portion that deals with lists
and unit tests. Both will each likely require similar effort to this.
2022-08-15 05:20:05 +02:00
BodgeMaster 3995e97f03 lib/javacompat: Make the endianness error message refer to the correct function 2022-08-15 02:07:00 +02:00
BodgeMaster c9ec524db1 test/nbt_size_helpers: Implement tests for valid input 2022-08-13 17:32:47 +02:00
BodgeMaster 73ae58e522 test/assert: Add line number to assertion failed message 2022-08-13 17:32:47 +02:00
BodgeMaster acc19ae100 lib/nbt: Change behavior of totalTagSize to treat encounters of compounds and lists as errors
I stumbled over this when writing the unit test. Previously, it would return
an error code but explicitly mark it as not being an error. This was intended
behavior but I decided to change it because I didn’t anticipate it when writing
the test.

Technically `ErrorOr<T>` can be used to pass any message alongside `T`,
but practically, it is reasonable to assume that the error code is
`ErrorCodes::SUCCESS` when `isError` is false. Therefore, this feature
should be really only used in the weirdest edge cases - if at all.
Even then, it is most likely still preferable to flag it as an error and
just hand the resulting `T` back using the long constructor
`ErrorOr<T>(bool, uint8_t, T)`.
2022-08-13 17:32:47 +02:00
BodgeMaster 149285c357 lib/nbt: Finish implementing containedDataLength, rename nextTagTotalSize->totalTagSize and nextTagDataLength->containedDataLength 2022-08-13 17:32:47 +02:00
BodgeMaster 0c92bdf8fd test/nbt_size_helpers: begin adding unit tests for lib/nbt's new nextTag size helpers 2022-08-13 17:32:47 +02:00
BodgeMaster 86f1ef596f lib/nbt: Begin implementing nextTagDataLength 2022-08-13 17:32:47 +02:00
BodgeMaster 027f324f03 lib/nbt: Fix a bug in nextTagTotalSize and significantly improve readability by removing redundant code 2022-08-13 17:32:47 +02:00
BodgeMaster f5d85da98c lib/nbt: Move the functions for getting tag sizes into the helper namespace, give up on handling lists the same as all other tags
I tried dealing with lists in the same way as with other more basic tags
but came to the conclusion that this is most likely not feasible in the same
way that it is not feasible for compounds. It would require a mini-parser
that can deal with all sorts of tags (including nested lists and compounds).

Instead, an approach more similar to the recursion for compound tags will
be used (using its own function to deal with the missing tag headers ofc).
2022-08-13 17:32:47 +02:00
BodgeMaster 396b9673fd lib/nbt: Various minor fixes to get the program to compile properly 2022-08-13 17:32:47 +02:00
BodgeMaster 68fbf3ae20 lib/nbt: remove a function used to get the next tag type which introduced unnecessary complexity 2022-08-13 17:32:47 +02:00
BodgeMaster 5400790e78 test/nbt*: rename files, move byte tag object test from helper test file into its own file 2022-08-13 17:32:47 +02:00
BodgeMaster c7dd5471dd lib/nbt: Start implementing NBT validator 2022-08-13 17:32:47 +02:00
BodgeMaster 8048dc8891 tools/hexnet: Put the new usage generator to use and remove prefixes for IPv4 and IPv6
The prefixes were part of a planned feature but since a connection is
either IPv4 or IPv6 but never both, it would have been completely useless
to specify which to use. Instead, only TCP and UDP will need to be specified.
2022-08-12 12:30:55 +02:00
BodgeMaster a1f16e6f6b lib/cli: Fix the usage text generator not dealing well with absent sections 2022-08-12 11:59:42 +02:00
Shwoomple cb7b5ddba7 lib/cli: Add usage generator. 2022-08-12 13:35:56 +05:30
Shwoomple e0648720bb tools/hexnet: Implement ipv6 support. 2022-08-11 22:55:12 +05:30
Shwoomple ebcf436a18 lib/cli: delete duplicate header file. 2022-08-11 18:57:22 +05:30
BodgeMaster aef91fe7cd test/nbt_helpers: Fix wrong test pass message 2022-08-04 07:50:20 +02:00
BodgeMaster 4af9003761 Code style: I just decided to accept that float and double exist and that we can just assume they are 32 and 64 bits repectively.
This isn't going to run on an Arduino or anything like that anyway.
2022-08-04 07:47:24 +02:00
Milan Suman 704b440d5a lib/nbt: Add tag classes 2022-08-04 00:01:12 +05:30
BodgeMaster 608767f5c2 tools/hexnet: Add more command line flags and options
This only adds the options to the parser. They aren't used anywhere in the code yet.
2022-08-02 03:42:37 +02:00
BodgeMaster e31bff0802 test/nbt_writestring_failure_mode: Add license information 2022-08-02 03:37:10 +02:00
BodgeMaster 5c73308934 Rename all headers from .h++ to .hpp
Idk why I did that in the first place. Probably bc hpp looks stupid.
But having a + in a file name bugs me just as much. And other ppl as well.
So I changed it.
2022-08-02 03:35:08 +02:00
BodgeMaster b59fe1857e lib/cli: minor refactoring to make things less confusing and nicer to use
I renamed "unpositional arguments" to "options" and "positional arguments" to "arguments".
This is intended to make the code more readable and easier to type out.
2022-08-02 03:16:54 +02:00
BodgeMaster 69f15e928a lib/cli: Add fields for a short description and additional usage information to the arguments parser
This is in preparation for building the help text generator.
2022-08-02 02:03:50 +02:00
BodgeMaster d0d02fc8d2 tools/hexnet: Move the TCP reading portion to a thread
This was too straight-forward to not just do it when I previously worked
on hexnet. Why didn't I just do it? Idk.
2022-08-02 01:07:20 +02:00
BodgeMaster 1308327fae tests: OCD fixes lol
sorry
2022-08-02 01:04:45 +02:00
BodgeMaster 4582c3e595 test/nbt_helpers: move the test that aborts to its own program 2022-08-02 00:41:11 +02:00
BodgeMaster 28719072bb fix a compiler warning 2022-08-01 16:39:18 +02:00
Milan Suman 4f1ad714bd lib/nbt.cpp: Implement writeString function 2022-07-28 17:15:04 +05:30
BodgeMaster adc9a7f36b tools/hexnet: prepare for multithreading
Multithreading will be needed to simultaneously receive and send data.

The preparations include:
- move all the settings of the program into global scope
- add mutexes
- move the code that reads from the TCP socket into a dedicated function
2022-07-25 15:55:40 +02:00
BodgeMaster b044503951 test/cli_argument_parser: get rid of useless parameters
(pointed out by compiler warning)
2022-07-23 10:55:03 +02:00
BodgeMaster 6baff11ebd test/cli_argument_parser: implement tests for generated error messages 2022-07-21 09:41:04 +02:00
BodgeMaster c9d6cf0b5e lib/cli: minor consistency changes 2022-07-21 09:39:45 +02:00
BodgeMaster a51c65c9f2 test/javacompat: get rid of a compiler warning 2022-07-20 19:22:06 +02:00
BodgeMaster 0dcc579bb5 test/cli_arguments_parser: extend some tests, implement all remaining parser tests except checking for error messages 2022-07-20 19:16:02 +02:00
BodgeMaster db3b133f88 lib/cli: fix trailing incomplete unpositional arguments
The parser used to rely on the next iteration of the loop to detect
if an unpositional argument was missing its value, this has now been
fixed by adding an additional check on unpositional arguments waiting
for a value that detects if the end of the loop has been reached
2022-07-20 18:30:25 +02:00
BodgeMaster 2cc2543b2a lib/error: fix compiler error with g++11 or newer
This wasprobably a syntax error on my part.
2022-07-20 09:58:58 +02:00
BodgeMaster a0d2974f0a test/cli_argument_parser: fix programmer-generated segfault 2022-07-20 08:46:06 +02:00
Milan Suman 4659946a2f src/test: free pointers 2022-07-20 12:13:47 +05:30
Milan Suman b5312aeb58 lib/nbt: implement readString NBT helper function 2022-07-20 12:08:04 +05:30
BodgeMaster 9562ae7be9 Merge branch 'master' of https://lostcave.ddnss.de/git/BodgeMaster/FOSS-VG 2022-07-20 08:07:03 +02:00
BodgeMaster b1733bc007 tools/hexnet: initial implementation of TCP receive only server 2022-07-20 08:06:45 +02:00
Milan Suman d315c6fcfc Merge branch 'broken' 2022-07-20 10:39:16 +05:30
Milan Suman 2f38636a27 lib/javacompat: implement exportJavaString 2022-07-20 10:38:55 +05:30
Milan Suman 0462756451 lib: rename java_string to javacompat 2022-07-20 08:44:56 +05:30
Milan Suman c1b6c3005f lib/java_string: fix end character issues 2022-07-20 08:39:29 +05:30
BodgeMaster 45538e156a lib/java_string: replace std::vector with std::string 2022-07-20 04:23:06 +02:00
BodgeMaster 34e30c0bd4 test/java_string: replace tabs with spaces, fix how tiny_utf8::string is being instantiated 2022-07-20 04:02:44 +02:00
BodgeMaster e184acde00 lib/java_string: rename functions
JavaCompat::importJavaFormatToString() → JavaCompat::importJavaString()
JavaCompat::exportStringToJavaFormat() → JavaCompat::exportJavaString()
2022-07-20 04:00:17 +02:00
BodgeMaster 09e2030a55 test/cli_argument_parser: More thorough unknwon flag test, add unknown unpositional argument test 2022-07-18 21:26:37 +02:00
Milan Suman 42336c560a Birthed an abomination, what the fuck 2022-07-18 12:13:10 +05:30
BodgeMaster 79f58a6242 lib/java_string: add placeholder functions 2022-07-17 13:02:45 +02:00
BodgeMaster 2cbf048f2e lib/cli: make flags return more accurate error codes
revealed by writing a test and it behaving differently from what I expected
2022-07-17 12:09:19 +02:00
BodgeMaster 4ceaca745b test/cli_argument_parser: notes outlining what additional tests are needed 2022-07-15 19:47:07 +02:00
BodgeMaster db6e543c5c test/cli_argument_parser: add a test for dealing with "empty" command lines 2022-07-15 19:46:20 +02:00
BodgeMaster 8835b90398 test/cli_argument_parser: rename everything to have nice long descriptive names
This is in preparation for adding more tests that require the same kinds of components.
2022-07-15 19:43:17 +02:00
BodgeMaster efa4fa560e tools/hexnet: replace built-in argument parser with lib/cli
This is the entire reason I build lib/cli in the first place:
Parsing arguments directly in a given program tends to get really messy,
not to mention all the different ways that arguments can be specified
and the redundant work required to do that on multiple programs.
2022-07-15 13:51:19 +02:00
BodgeMaster 4c3d2fdbbf lib/cli: ArgumentsParser constructor can accept both char** and const char** 2022-07-15 13:49:43 +02:00
BodgeMaster 3b1d288d1e test/cli_argument_parser add an assertion to the valid input test that expects the value of unpositional arguments that are not present to be "" 2022-07-15 13:44:56 +02:00
BodgeMaster b18a97713d test/cli_argument_parser: fix using delete instead of delete[] on pointer array 2022-07-15 11:47:19 +02:00
BodgeMaster 9ce979aa7c lib/cli: first unit test implemented 2022-07-15 11:33:02 +02:00
BodgeMaster 82d611b984 lib/cli: various fixes
- argumentWaitingForValue was never reset after the value had been retrieved
- made it so the ArgumentsParser constructor can accept const char**
- correct usage of substr() and actually use the correct position in the first place
- fix a typo where I tried to dereference `this` with `-` instead of `->`
2022-07-15 11:21:18 +02:00
BodgeMaster f5b0b74f94 lib/cli: remove useless arguments from getters, remove useless getter getProgramName (made the string public instead) 2022-07-15 09:11:39 +02:00
BodgeMaster a1223ea4b9 Minor improvements and fixes.
test/nbt_helpers: add a headline to output
Build system: remove comma from array that I added bc I thought it was correct sytax, it wasn't
lib/cli: change argument order of PositionalArgument constructor to fit in with Flag and UnpositionalArgument
lib/cli: properly define what is private and what is public in the ArgumentsParser class
2022-07-15 08:54:09 +02:00
BodgeMaster 390087fc35 lib/cli: finish initial implementation
This should be all functionality that is needed for now.
The next step is building unit tests to check that everything works correctly.

Who am I kidding? There will most certainly be bugs in there given that this
code has been typed out without ever being run.
2022-07-14 04:57:48 +02:00
BodgeMaster a2084e296a lib/error: Remove ErrorOr<T>(bool) constructor
This allows ErrorOr<T> to be used for bool, as there would be conflicting
constructors otherwise.

Also, we have ErrorCodes::UNKNOWN now so, instead of `ErrorOr<T>(true)`,
`ErrorOr<T>(true, ErrorCodes::UNKNOWN)` can be used.
2022-07-14 03:58:13 +02:00
BodgeMaster e6f4884b60 lib/error: finally removed that useless cpp file 2022-07-14 03:16:58 +02:00
BodgeMaster 91f3dfaa5e lib/cli: Add a library for command line arguments parsing
This has the parser itself already implemented, all other functionality is still
missing. So are tests.

Yes, I’m making my own getopt. Let me.
2022-07-14 03:13:48 +02:00
BodgeMaster 7e049fcfd1 lib/error: rename and add error constants 2022-07-13 22:01:18 +02:00
BodgeMaster c406555e4e tools/hexnet: argument parser fix 2022-07-13 20:35:33 +02:00
BodgeMaster 5cb1a52ec4 tools/hexnet: replace "server" with "listen" because that's what netcat calls it and the argument we use is -l like netcat's listen mode 2022-07-13 20:30:27 +02:00
BodgeMaster 9639ef065f tools/hexnet: Work on argument parser to finish suppurt for client mode 2022-07-13 20:27:58 +02:00
BodgeMaster 310011a6da tools/hexnet: replace exit codes with macros to improve readability 2022-07-13 06:06:09 +02:00
BodgeMaster 6a5096dfa3 tools/hexnet: add server/client concept to arguments parser 2022-07-13 06:03:41 +02:00
BodgeMaster b3cd8709fb Tools: Add WIP hexnet tool. This will be similar to hexdump and netcat in one.
Yes, I am using this as an exercise for myself to figure out networking.
2022-07-12 05:13:01 +02:00
Shwoomple 68484c6a20 NBT: Moar nbt helper functions. Add all functions in issue #18 except writeString 2022-07-06 18:28:02 +05:30
Shwoomple 847b73c6ae NBT: implement the overloaded writeInt8Array 2022-07-06 17:16:47 +05:30
Shwoomple 8d8c1e6b90 NBT: change "[]" to "Array" in unit test messages. 2022-07-06 16:28:08 +05:30
Shwoomple b0ccc74409 NBT: Added writeInt8Array. 2022-07-06 16:27:32 +05:30
BodgeMaster 762ba7f089 NBT: add write helpers for float types 2022-07-04 19:43:31 +02:00
BodgeMaster 8c7be385ae NBT: add write helpers for int32 and int64 2022-07-04 18:29:38 +02:00
BodgeMaster 6d62d995df NBT: implement write helpers for int8 and int16 2022-07-04 18:03:40 +02:00
BodgeMaster 044593e081 NBT: add compiler errors to the endian specific sections 2022-07-02 16:41:54 +02:00
BodgeMaster 664632d111 NBT: add stub write helper functions 2022-07-02 02:08:32 +02:00
BodgeMaster 4f9577eb36 NBT: implement readFloat helpers 2022-07-01 21:15:18 +02:00
BodgeMaster 975cdd309d NBT: implement NBT::helper::readInt64Array 2022-06-30 11:02:30 +02:00
BodgeMaster edcf40d5a5 NBT: implement NBT::helper::readInt32Array 2022-06-30 10:45:12 +02:00
BodgeMaster 562fbcecbb remove pointless placeholder, rename /test to /test_data because the actual tests live in /src/test 2022-06-29 12:34:27 +02:00
BodgeMaster c87c519bb5 NBT: implement NBT::helper::readInt8Array 2022-06-29 12:22:54 +02:00
BodgeMaster 71fab21dfb Error: add OVERRUN_ERROR 2022-06-29 11:32:33 +02:00
BodgeMaster d43ef67ed1 NBT: fix bug in readInt64, improve readability 2022-06-29 00:05:02 +02:00
BodgeMaster ed429633e5 NBT Test: fix begin of data test for int64, remove irrelevant (and architecture-specific) suffixes 2022-06-29 00:02:51 +02:00
BodgeMaster 7c12a92b2a NBT: implement the integer helper functions 2022-06-28 22:04:04 +02:00
BodgeMaster 12b4a8bb55 Tests: fix up alias and implement first tests 2022-06-28 22:03:27 +02:00
BodgeMaster d37f5581c3 assert.h++: fix failure handling 2022-06-28 20:11:24 +02:00
BodgeMaster c61aca5b72 assert.h++: simple ASSERT() macro 2022-06-28 19:55:22 +02:00
BodgeMaster e09fb6a61f add test infrastructure, closing #11 2022-06-28 18:28:44 +02:00
BodgeMaster 4f760f44be NBT: Implement readInt8 helper closing #2 2022-06-28 16:58:31 +02:00
BodgeMaster 12e9533772 apparently that's not how cpp works (I stole it from somewhere lol) 2022-06-28 16:51:52 +02:00
BodgeMaster 8594f4cbb0 NBT: Fix ambiguity between int types and bool when calling the ErrorOr<> constructor 2022-06-28 16:13:33 +02:00
BodgeMaster 83d606a2c7 Error: Add error codes to ErrorOr<> and add constructors
This allows us to handle functions that can fail in multiple different ways
2022-06-28 16:01:39 +02:00
BodgeMaster 081035db32 expose helpers in the header, rename NBT::helpers to NBT::helper 2022-06-28 15:19:47 +02:00
BodgeMaster ab920a114b comply with code style guidelines, also minor fix to them 2022-06-28 14:25:32 +02:00
BodgeMaster 9b58d165c0 We have a suitable string type for UTF-8 now. 2022-06-27 18:15:01 +02:00
BodgeMaster b0bd027898 Add license and copyright notices 2022-06-27 11:46:13 +02:00
BodgeMaster f80a33ddb0 start implementation of NBT parser 2022-06-27 04:50:32 +02:00
BodgeMaster 5ea835dbb5 add Serenity-style ErrorOr<> type 2022-06-27 04:46:22 +02:00
BodgeMaster 89e7a89e88 remove leftover useless information from previous NBT model 2022-06-26 01:24:50 +02:00
BodgeMaster cad04d8e12 Adjusted the model and finished figuring out / writing down the spec 2022-06-25 13:37:57 +02:00
BodgeMaster 0d10af1bd6 do not use the lib prefix for library names 2022-06-24 16:50:41 +02:00
BodgeMaster bb0dc05a30 rename header
Yes, this is a completely necessary change, I am aware.
2022-06-24 12:19:41 +02:00
BodgeMaster 6e4dd4da71 Remove build system test code, add generalized NBT model 2022-06-24 12:15:34 +02:00
BodgeMaster 0c9299b21d Create files for nbt library and a tool to use it.
These files were also used to figure out the process of building them so
their content is garbage.
2022-06-24 09:28:17 +02:00
BodgeMaster 241100e1ab add placeholder files because Git doesn't handle empty folders 2022-06-24 06:42:19 +02:00