Updating the Z-Machine Standard Documents

Yes. Since font 4 is essentially a synonym for fixed pitch and fixed pitch is always required for the upper window, it makes no sense for an interpreter not to support font 4.

But if the entire display is fixed-pitch, supporting it may mean doing nothing. (Except returning a success value for @set_font.)

Section 8.3.1.1 has an off-by-one error giving the true colour window property numbers as 17 and 18. The properties are numbered 16 and 17, but when counting are the 17th and 18th respectively due to numbering beginning with zero.

The final sentence in Section 8.8.3 is confusing/misleading:

Each window has a position (in units), a size (in units), a cursor position within it (in units, relative to its own origin), a number of flags called “attributes” and a number of variables called “properties”.

The window position, size, and cursor position are actually among the properties. The sentence implies they are separate.

The Tandy bit is not marked as being valid for a game to alter, but the Remarks say

In ‘The Witness’, the Tandy Flag can be set while playing the game, by typing $DB and then $TA.

This does indeed work, although it’s clearly a debugging tool left in the code.

Should games be allowed to set and unset this flag, or should interpreters be allowed to make this debugging feature in The Witness fail?

1 Like

I mentioned this one a long time ago. My opinion is that changing the bit is legal because an existing Infocom game has in-game commands to change it, and it does indeed work on Infocom’s interpreters.

I’m trying to remember if I found any other examples of games changing parts of the header, but I don’t recall off the top of my head.

Edit: Oh, of course bits 0, 1, and 2 of Flags 2, which are already marked as legal for a game to change. Not sure about any others.

1 Like

The 1.0 Standard specifies external file naming as follows:

7.6.1

******* Filenames have the following format (approximately the MS-DOS 8.3 rule): one to eight alphanumeric characters, a full stop and zero to three alphanumeric characters (the “file extension”).

7.6.1.1

The interpreter must convert all filenames to upper case before use. If no full stop is given, “.AUX” should be appended.

7.6.1.2

Games should avoid the extensions “.INF”, “.H”, “.Z” followed by a number or “.SAV”: otherwise they may be in danger of erasing their own object code, source code or saved game files.

The 1.1 Standard allows for games to explicitly avoid prompting the user for a filename when creating new files, which opens up the possibility of all sorts of dangerous behaviour. The file naming section was hastily updated to try to mitigate this problem, but in its current state (on inform-fiction.org) it is slightly contradictory and also manages to refer to interpreters as ‘the library’.

I have attempted to rewrite it with a bit more clarity:

7.6.1

***[1.1] The game can pass any string to the interpreter to be used as a filename. In all cases the interpreter will convert the string to an appropriate filename.

It is no longer required that interpreters or games stick to the format specified in previous versions of this Standard (approximately the MS-DOS 8.3 rule), but it is given here for reference: one to eight alphanumeric characters, a full stop and zero to three alphanumeric characters (the “file extension”).

7.6.1.1

The interpreter must convert all filenames to upper case before use.

7.6.1.2

***[1.1] The interpreter should delete from the filename any characters illegal for a filename. This will include all of the following characters (and more, if the OS requires it): slash, backslash, angle brackets (less-than and greater-than), colon, double-quote, pipe (vertical bar), question-mark, asterisk. The library should also truncate the filename at the first full stop (delete the first full stop and any following characters). If the result is the empty string, change it to the string “NULL”.

Although the interpreter should truncate the filename at the first full stop, games should be safe and avoid extensions such as “.INF”, “.H”, “.ZIL”, “.ZAP”, “.Z” followed by a number, or “.SAV”: otherwise they may be in danger of erasing their own object code, source code or saved game files.

7.6.1.3

***[1.1] The interpreter may add any appropriate file extension (that is, a full stop followed by a further string that identifies the type of the file) to the filename. Previous versions of this Standard suggested a default file extension of “.AUX”, but this is not a requirement.

7.6.1.4

***[1.1] The interpreter may save the file in a location other than the location of the game file, but it should ensure that the file is easily accessible to users outside of the game, to allow the files to be moved to other locations or devices.

7.6.1.5

***[1.1] When reading a file without using a prompt to the user, the interpreter may choose to search for the file using any algorithm of its choice, starting from the argument the game passes. For example, if the argument specifies a filename containing a file extension, the interpreter may choose to look for a filename with that extension and read it if it is found.

Glk interpreters won’t be able to control exactly how the filename is cleaned, but the main thing is that it will still be consistent between calls to save and restore.

It looks like the inconsistency regarding extensions is still present.

Zero length names are valid after all…they should be changed to “NULL” by a standard interpreter.

The following needs more work I think:

As an example, both the “?” and ASCII control codes are valid in linux filenames, but allowing either is probably a bad idea. Instead of calling out some of the problematic characters, it makes more sense to whitelist what is allowed, i.e. probably just alphanumeric. Even allowing ASCII NUL could cause an interpreter to treat a filename differently than the underlying OS.

Cross-platform filenames are hard. Even restricting characters isn’t enough to guarantee it, since there are reserved names on Windows made up entirely of legal characters. But that is definitely outside the scope of the standard.

The first quote here comes after text which reads

It is no longer required that interpreters or games stick to the format specified in previous versions of this Standard’.

This is simply a description of what the Standard previously required.

Perhaps simplest to add something like:

The interpreter should do its best to ensure that the game is not allowed to save files in any location or with any name that will allow it to overwrite or interfere with files for other programs, especially system files.

My thoughts were along these lines: It is not obvious or trivial for an interpreter author to understand all the possible threats presented from unprompted saving of files using names generated by an attacker. Instead of a vague warning, something concrete like “filter out all non-alphanumeric characters” is simple and safe. If that is too restrictive, then allowing a few extra printable ASCII characters is ok as long as they are proven safe. Again, a whitelist is the safest option, because the suggested filename can have any byte value.

Thanks, I misunderstood.

What about Unicode file names?

Since they are byte strings, they are assumed to be ASCII. I suppose you could specify UTF-8 or something to get unicode names, but that’s an even worse security nightmare. I’d never implement that. Most unicode implementations even in major OSes are really bad at corner cases. Heck sometimes they struggle to get even the common cases right.

ZSCII, not ASCII, surely? Oh no, I’m wrong, ASCII is what the current spec says. A little bit odd, to be honest.

Agreed, it is a pain, I went to a lot of trouble to make my jzip version work with Unicode file names (and this is part of the reason I haven’t released a new version in years). However should the standard forbid them?

My reasoning for trying to support Unicode was that people playing a game in their native language shouldn’t be forced to use English file names.

I think file names should not be restricted to ZSCII or ASCII, or even the Unicode BMP. But that’s just me.

When the story file specifies a file name a data file using @save, the spec says it is ASCII. That seems reasonable (even though it’s perhaps the only use of ASCII in the spec.) Though if it’s printable ASCII, not Latin-1, then they actually are identical in ZSCII, so never mind.

When the user provides a file name, I don’t the spec says anything, and it probably shouldn’t. Glk terps may not even have access to the file name.

The only edge case is sending the user provided file name to stream 4, which is filed as stream 4 and non-ZSCII filenames · Issue #66 · iftechfoundation/Z-Machine-Standard · GitHub

1 Like

The interpreter can support any filenames it likes, but when the game is providing a filename (as a suggestion or without a prompt), it is reasonable to limit it to ASCII.

1 Like

My mistake, I thought the discussion had moved to the interpreter sanitizing user file names instead of auxiliary file names.

Nah, if the user wants to deliberately save over important system files from a z-machine game, it’s not up to the standard to try to stop them. If a game wants to do this, the interpreter needs to step in.

3 Likes