DavidGriffith / frotz

Infocom-style interactive fiction player for Unix and DOS (moved to https://gitlab.com/DavidGriffith/frotz)
GNU General Public License v2.0
209 stars 64 forks source link

@output_stream handled improperly #1

Closed DavidGriffith closed 10 years ago

DavidGriffith commented 10 years ago

This was sent in by David Fillmore today:

According to the Z-Machine specification: "In Version 6, a width field may optionally be given: if this is non-zero, text will then be justified as if it were in the window with that number (if width is positive) or a box -width pixels wide (if negative). Then the table will contain not ordinary text but formatted text: see print_form."

Frotz, on the other hand, tries to get the width of a window of number -width if the value is <= 0, but passes the width value through directly if it is positive. This results in the interpreter crashing with an "Illegal window" error if the width value is less than -7.

Sample Inform6 code tickling this bug:

Switches v6;
Array formatted table 50;
[ main x;
  @output_stream 3 formatted (-30);  ! Frotz treats this as a window number and crashes.
  print "ooh, hello there^boy^how are you";
  @output_stream (-3);
  @print_form formatted;
  @read_char 1 -> x;
];
DavidGriffith commented 10 years ago

I guessed that the problem might be in get_max_width() in src/common/screen.c. He responded thus: "I looked into the source for Windows Frotz a bit, and I think the problem is in redirect.c, in memory_open(). What Now, I don't actually write C, but that's converting xsize to a positive number and sending the result to get_max_width, if x-size is negative. What's it's supposed to be doing is sending xsize to get_max_width if it's positive, but if it's negative, just converting xsize to a positive number and taking it directly (not checking a window)."

The offending code is this:

        if (buffering && (short) xsize <= 0)
            xsize = get_max_width ((zword) (- (short) xsize));
DavidGriffith commented 10 years ago

Fixed.