- Removed a bug with attempt to include pure c headers
- Added some more information about the license - fennec::file implementation
This commit is contained in:
67
PLANNING.md
67
PLANNING.md
@@ -6,7 +6,7 @@
|
||||
|
||||
1. [Introduction](#introduction)
|
||||
2. [TODO](#todo)
|
||||
1. [Security Ramblings](#security-ramblings)
|
||||
1. [Security Ramblings](#file-security-ramblings)
|
||||
3. [C++ Language](#c-language-library-lang)
|
||||
4. [Math Library](#math-library-math)
|
||||
5. [Memory Library](#memory-library-memory)
|
||||
@@ -63,6 +63,7 @@ This however can be achieved using events at different stages of those engines t
|
||||
- 2D Physics (`physics2d`)
|
||||
- 2D & 3D Audio (`audio`)
|
||||
|
||||
|
||||
### File Security Ramblings:
|
||||
|
||||
Windows is starting to piss me off, so I am considering dropping official support for MSVC. MinGW and Cygwin
|
||||
@@ -78,41 +79,41 @@ The crux of this issue falls at the following specific behaviour:
|
||||
- Application interface confirms overwrite action
|
||||
- Application writes to the file after confirmation
|
||||
|
||||
A threat actor can introduce a malicious file or symlink to the file that was attempted access between the check and
|
||||
A threat actor can introduce a malicious file or symlink to the file that was attempted access between the check and
|
||||
usage of the file. This is called TOCTOU (time of check, time of use).
|
||||
|
||||
This issue can be solved using `fopen("<file>", "w+")`, however this specific behaviour is not intuitive to those first
|
||||
learning how to work with file systems. We can attempt to abstract this away with another wrapper, or simply write
|
||||
the file structure to handle this behaviour properly. The downside to this method overall is that it will break
|
||||
common conventions of how humans interpret filesystems and the related control flow logic. What we can do is force the
|
||||
`'+'` flag to always be present for write operations, and raise an error when desired, if the file is not empty. This
|
||||
This issue can be solved using `fopen("<file>", "a+")` and `ftell`, however this specific behaviour is not intuitive to
|
||||
those first learning how to work with file systems. We can attempt to abstract this away with another wrapper, or simply
|
||||
write the file structure to handle this behaviour properly. The downside to this method overall is that it will break
|
||||
common conventions of how humans interpret filesystems and the related control flow logic. What we can do is force the
|
||||
`'+'` flag to always be present for write operations, and raise an error when desired, if the file is not empty. This
|
||||
unfortunately would have the downside of being unable to open a file as write only.
|
||||
|
||||
Using `"wx"` in this instance would not be sufficient since it would require a second call to fopen, which would
|
||||
Using `"wx"` in this instance would not be sufficient since it would require a second call to fopen, which would
|
||||
create the conditions for the TOCTOU error described above.
|
||||
|
||||
Another issue arises when we are parsing a directory tree. The best we can do is take ownership of the directory that
|
||||
is opened as the root. However, this requires `dirent.h` which is not implemented in MSVC. A custom implementation of
|
||||
`dirent.h` may be written for MSVC, however this is one of the few things I am not willing to outsource to another
|
||||
library. Developing our own implementation would take a non-insignificant amount of time, between writing the library,
|
||||
debugging it, and testing for vulnerabilities. As stated above, this implementation is native to MinGW and Cygwin,
|
||||
so we would not have to entirely drop support for Windows. However, MSVC is the most widely used compiler for Windows
|
||||
Another issue arises when we are parsing a directory tree. The best we can do is take ownership of the directory that
|
||||
is opened as the root. However, this requires `dirent.h` which is not implemented in MSVC. A custom implementation of
|
||||
`dirent.h` may be written for MSVC, however this is one of the few things I am not willing to outsource to another
|
||||
library. Developing our own implementation would take a non-insignificant amount of time, between writing the library,
|
||||
debugging it, and testing for vulnerabilities. As stated above, this implementation is native to MinGW and Cygwin,
|
||||
so we would not have to entirely drop support for Windows. However, MSVC is the most widely used compiler for Windows
|
||||
applications and is native to Visual Studio and VSCode.
|
||||
|
||||
What is probably the best solution is to wrap everything in a file interface that does not allow the direct setting of
|
||||
What is probably the best solution is to wrap everything in a file interface that does not allow the direct setting of
|
||||
these flags. Then we set our own usage type for the file that informs which flags should be used.
|
||||
|
||||
We need to be able to handle the following types of files:
|
||||
- Assets, such as scenes, audio, textures, metadata, meshes, etc.
|
||||
- Save files, setting files, etc.
|
||||
|
||||
One of the nice things about the assets is that they are guaranteed to be read-only once an application is installed
|
||||
One of the nice things about the assets is that they are guaranteed to be read-only once an application is installed
|
||||
on the computer of the end-user. Therefore, this issue only arises with save files and custom file formats.
|
||||
|
||||
When the editor is run, all these files should be opened in read/write mode.
|
||||
|
||||
Naming conventions should exist for the types of files and how they are read. For example, in release mode,
|
||||
most assets should be opened once, and then closed immediately. However, this does not make sense for formats
|
||||
Naming conventions should exist for the types of files and how they are read. For example, in release mode,
|
||||
most assets should be opened once, and then closed immediately. However, this does not make sense for formats
|
||||
that are continuous and too large to be kept around in memory, such as video formats.
|
||||
|
||||
Perhaps the following conventions:
|
||||
@@ -120,23 +121,41 @@ Perhaps the following conventions:
|
||||
- Stream Asset
|
||||
- Resource
|
||||
|
||||
We can turn this into an object-oriented approach by having different formats inherit these base types. We may still
|
||||
We can turn this into an object-oriented approach by having different formats inherit these base types. We may still
|
||||
have a base file type that wraps C functionality, but discourage developers from using the interface.
|
||||
|
||||
We could also declare the file interface extern so that only internal files know the implementation. However, I would
|
||||
We could also declare the file interface extern so that only internal files know the implementation. However, I would
|
||||
not be satisfied by doing this since it would prevent developers from implementing custom file type implementations.
|
||||
|
||||
Conserving memory is not really an issue here as long as we are smart about our implementation. Files should only be
|
||||
open when necessary and be closed when it is no longer necessary to have them open.
|
||||
Conserving memory is not really an issue here as long as we are smart about our implementation. Files should only be
|
||||
open when necessary and be closed when it is no longer necessary to have them open. Data should be streamed unless the
|
||||
all the data in the file is required.
|
||||
|
||||
When built in release mode, we also need to pack static assets into some sort of archive that is mountable to reduce
|
||||
disk space consumption of a program. I am considering encryption for archives, but there likely is not much of a point.
|
||||
When built in release mode, we also need to pack static assets into some sort of archive that is mountable to reduce
|
||||
disk space consumption of a program.
|
||||
|
||||
I was considering encryption for archives, however it does not make much sense. Assuming someone intends to pirate the
|
||||
game, there is not much stopping them from running the files. I will add Steam support at some point which would allow
|
||||
you to use Steam's DRM to prevent the executable from being run. Otherwise, there is no point in attempting to encrypt
|
||||
game files. Even Unreal PAK files can be cracked in seconds, and even if I managed to write something that cannot be
|
||||
trivially cracked locally, you can scrape most assets from the GPU and Audio Card.
|
||||
|
||||
I have managed to solve the specific case provided at the top of this section, which was done by wrapping C I/O calls
|
||||
into a file wrapper. This wrapper can handle a few different mode flags and has specific conditions for the flags. See
|
||||
the documentation for `fennec/fproc/io/file.h` for more info.
|
||||
|
||||
One question remains unanswered on this front; should a read/write file open as `r+` or `a+`. `rewind` is slightly faster
|
||||
than `fseek(SEEK_END)`, however for the case of save files and editor assets, `r+` makes more sense from a usage perspective
|
||||
|
||||
Directories remain an issue, with `dirent.h` being the only sensible option at time of writing. The issue with using
|
||||
`dirent.h` boils back down to security issues on Windows. However, the only option is to write a custom implementation
|
||||
for MSVC.
|
||||
|
||||
|
||||
## C++ Language Library (`lang`)
|
||||
|
||||
Implement header files for standard functions relating to the C++ Language.
|
||||
|
||||
So far this is implemented on an as-needed basis. A full implementation should be worked on continuously.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user