Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Glulx display bug in Rover's Day Out (linux 32 bit)

3 views
Skip to first unread message

Otto Grimwald

unread,
Oct 31, 2009, 4:19:28 PM10/31/09
to
In the game Rover's Day Out, some people pointed a display bug in the
dialogues, on the Linux x86 version of gargoyle (the text is replaced by
???????)
This bugs affects also the console versions of Git and Glulxe.

With Ben Cressey we made some investigations to learn more about it,
trying it on different OS and hardware (trying indifferently gargoyle,
when available, or console git/glulxe):

- Linux (32 bit): the bug is present
- Linux (64 bit): works perfectly
- Linux PPC: works perfectly
- Windows 32 bit: works perfectly
- Haiku (32 bit): works perfectly
- FreeBSD (32 bit): works perfectly

When trying to compile the source code (located at
http://code.google.com/p/rovers-day-out/), it even crashes gnome-inform7
(but I can release it anyway).

Basically, it's present only on Linux 32 bit. Why? The same interpreters
source code and the same game are used on all the tested plateforms.

The I7 code which is problematic is this part:

To say (dialogue - some text) in metaspeak:
if Real Thing is happening or Boarding Party is happening or Back on
Mars is happening:
the rule succeeds;
otherwise:
say paragraph break;
say first custom style;
say "[dialogue in fancyprint]";
say roman type;
say variable letter spacing;
say paragraph break.

To say (dialogue - some text) in fancyprint:
(- FancyPrint ({dialogue}); -).

Include (-

Constant SPACE = 32;
Constant RIGHTMARGIN = 60;

Array BigBuffer -> 1024; !big enough to hold the largest metatext

[FancyPrint caption i linelen;
caption.print_to_array(BigBuffer);
linelen = 0;
for (i=WORDSIZE : i < BigBuffer-->0+WORDSIZE : i++){
if (BigBuffer->i == '*'){
print "^";
linelen = 0;
continue;
}
if (linelen > (RIGHTMARGIN - 5) && BigBuffer->i == SPACE){
print "^ ";
linelen = 7;
continue;
}
print (char) BigBuffer->i;
linelen++;
}
rtrue;
];

-).


If I replace: say "[dialogue in fancyprint]";
by : say "[dialogue]";

the whole text is displayed on linux 32 (even if not formatted as
expected), and I can compile it in gnome-inform7.

Could it be related to how memory is handled on those different OS?

Matthew Wightman

unread,
Nov 1, 2009, 5:20:16 AM11/1/09
to
On Oct 31, 8:19 pm, Otto Grimwald

<contact_is_on_webs...@anamnese.fr.st> wrote:
>
> The I7 code which is problematic is this part:

[Some I7 code snipped]

> Array BigBuffer -> 1024; !big enough to hold the largest metatext
>
> [FancyPrint caption i linelen;
>         caption.print_to_array(BigBuffer);

<pedant>
I'd suggest replacing the above line with "caption.print_to_array
(BigBuffer, 1024);".
</pedant>

I seriously doubt this is in any way related to the problems you've
encountered, but as I haven't managed to reproduce them on my
(relatively-ancient) 32-bit Linux box, I've not been able to confirm
that. ;)


>         linelen = 0;
>         for (i=WORDSIZE : i < BigBuffer-->0+WORDSIZE : i++){
>                 if (BigBuffer->i == '*'){
>                         print "^";
>                         linelen = 0;    
>                         continue;
>                 }
>                 if (linelen > (RIGHTMARGIN - 5) && BigBuffer->i == SPACE){
>                         print "^       ";
>                         linelen = 7;
>                         continue;
>                 }
>                 print (char) BigBuffer->i;
>                 linelen++;
>         }
>         rtrue;
> ];
>
> -).
>

--
Matthew

Otto Grimwald

unread,
Nov 1, 2009, 7:31:38 AM11/1/09
to
Matthew Wightman wrote:
> <pedant>
> I'd suggest replacing the above line with "caption.print_to_array
> (BigBuffer, 1024);".
> </pedant>
>
> I seriously doubt this is in any way related to the problems you've
> encountered, but as I haven't managed to reproduce them on my
> (relatively-ancient) 32-bit Linux box, I've not been able to confirm
> that. ;)

hey, that's great, because thanks to your suggestion, there is no longer
this bug in the display.
It doesn't explain why we had this bug on several 32 bit linux systems
(could it be related to the kernel used and the way it handles memory?)

Andrew Plotkin

unread,
Nov 6, 2009, 1:28:32 AM11/6/09
to
Here, Matthew Wightman <matthew....@gmail.com> wrote:
> On Oct 31, 8:19�pm, Otto Grimwald
> <contact_is_on_webs...@anamnese.fr.st> wrote:
> >
> > The I7 code which is problematic is this part:
>
> [Some I7 code snipped]
>
> > Array BigBuffer -> 1024; !big enough to hold the largest metatext
> >
> > [FancyPrint caption i linelen;
> > � � � � caption.print_to_array(BigBuffer);
>
> <pedant>
> I'd suggest replacing the above line with "caption.print_to_array
> (BigBuffer, 1024);".
> </pedant>

Matthew looked at this further and then contacted me. As it turns out,
if you call print_to_array() with a single argument -- an address,
but no array size -- then the I6 code does something stupid. It
starts writing to an array of length $7FFFFFFF.

In my reference Glk libraries, this happens to work -- as long as you
don't in fact write past the end of the array. Of course, this is a
serious bug waiting to happen. An overflow could crash the game, or
crash the interpreter. A malicious overflow could conceivably eat your
computer.

More generally, this constrains the VM implementation. It should be
legal for the interpreter to allocate the string array separately, and
then copy it back to Glulx memory when the printing is complete. (This
is already how Unicode print-buffering works, due to endian issues.)
Such a strategy is liable to go squish in the face of a two-gigabyte
string array.

(It's the Glulx Inform veneer code being stupid. All my fault.
I'm sure I thought about this in 1998, and decided it wouldn't be a
big problem. Like all small problems that are ignored, it has grown.)

Anyhow. I have implemented a small patch to Glulxe which checks for
this sort of overflow, and treats it as a fatal error.

For the I6 Glulx author, this means that the String class's
print_to_array() method *must* be called with two arguments. The
one-argument form will die. And this applies to old Glulx games as
well; it's an interpreter change, not a compiler change.

The I7 compiler does not use print_to_array(), and I don't believe it
ever has. So this does not directly impact I7 authors. However, as you
can see above, some authors may be using I6 code with this idiom. Or
it might be in extensions.

My clever plan at this point is to put out the updated interpreter,
and try to find out how many existing games it breaks. If it's not
many, or if they can plausibly be fixed, I'll make the patch
permanent.

The alternate solution is for the interpreter to accept Stupidly Long
Arrays, and silently truncate them at the end of VM memory. This would
rule out interpreter crashes and security holes, but an overflowing
print_to_array() could still corrupt game state.

The Glulxe interpreter source patch is up at
<http://eblong.com/zarf/tmp/arraylimit.patch>,
or get the whole source package at
<http://github.com/erkyrath/glulxe/tree/arraylimit>.

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*

Al

unread,
Nov 6, 2009, 2:58:34 PM11/6/09
to
On Oct 31, 1:19 pm, Otto Grimwald

<contact_is_on_webs...@anamnese.fr.st> wrote:
> In the game Rover's Day Out, some people pointed a display bug in the
> dialogues, on the Linux x86 version of gargoyle (the text is replaced by
> ???????)
> This bugs affects also the console versions of Git and Glulxe.

> Could it be related to how memory is handled on those different OS?

I also had a problem compiling the game under 5Z71. I was able to get
an output file but the compiler came up with the printanytoarray error
in
the Mac and Windows compiler.

0 new messages