Although we had a discussion about this topic some times ago, I forgot the thread and set this new topic.
Supporting I/O library enables us to do a various things. In particular, writing/reading a file enables us the collaboration with external programs. For example, if an AI player writes the status of the game to a text file periodically, an external program can use the written status for the notifications of dead lock or some other issues in the game.
However, as prissi had indicated before, the default I/O library of squirrel does not have a limitation of directory traversal. This means that the squirrel script can read and write files outside of simutrans and can be used for malicious purpose. Simutrans should not be a platform for malware and we should impose proper regulations in file reading and writing.
Fortunately, all codes of the squirrel engine are embedded in the simutrans code, and we can modify them. What we have to do is to restrict reading and writing file outside of the simutrans data directory. This restriction can be implemented to file.open() function of squirrel. The code of that squirrel function is sqstd_fopen() function in squirre/sqstdlib/sqstdio.cc:10.
So, I propose to modify sqstd_fopen() function not to allow reading/writing files outside of the simutrans data directory and enable the squirrel standard I/O library.
Where do you want to write/read files? I think it would be best to dedicate a separate directory for output of scripts (an extra directory like for savegames). It could happen that the script is in a read-only part of the file system.
I don't have a request about the place of input/output files. Yes, using a dedicated directory for file input and output may be the simplest solution for the security concern.
How will you implement the file reading and writing? Do you modify and enable the standard i/o library of squirrel? Or, do you implement the new file i/o class with C++ code?
I have not thought about implementation aspects yet.
The i/o library of squirrel standard library does not provide an easy way to read and write multi-byte characters. Thus, I think that convenient functions to read and write multi-byte characters should be implemented with C++ code.
For example, a squirrel wrapper of fprintf() function can be convenient to read and write strings with multi-byte characters.
Since Simutrans uses internally only UTF-8, C functions should reasonably well handle multibyte (UTF-8) strings without the need for a wrapper. I would rather say you would need a function like fgetUTF8char or expose the unicode converter in Simutrans?
Maybe a function like fgetUTF8char does well. In squirrel standard library, you use file.readn() (http://www.squirrel-lang.org/squirreldoc/stdlib/stdiolib.html#file.readn) function to read a file. However, this function handles integer and floating decimal. Using this function in 8-bit unsigned integer mode works like getc() function of C language, but this approach cannot handle UTF-8 characters.
This is a tiny implementation to support read and write files with multi-byte characters.
This patch extends the Squirrel standard i/o library. The following functions are added to file class.
- file.readstr(n) ... Read up to n（integer ）bytes from the file and return text as String .
- file.writestr(str) ... Write str (String) to the file.
As it was discussed, the path restriction should be implemented. Anyway, this implementation works.
I apologize for reviving this topic.
This has already been implemented ?, since it can be very useful to import coordinates from a "ppm" image to build objects or vias.
Look here: https://forum.simutrans.com/index.php/topic,21099.msg196733.html#msg196733
This thread does not seems to be related to squirrel API...