[comp.sys.acorn] Bug in RISC OS Library

ferdo@neabbs.UUCP (FERDINAND OEINCK) (04/16/91)

Another bug in the RISC OS Library version 3.1b
===============================================

The bug appears to be in the file 'win.c'.

Suppose you want to deliver null events to a particular 'unknown event
processor'.
To do so first call:
        prev_idle_claimer = win_idle_event_claimer();
to get the previous null events claimer window handle.
Now call:
        win_claim_idle_events(-1);
to ensure all events are processed by 'unknown event processors' instead of
a delivery to a particular window.

The -1 parameter in this last call will be one part of the bug as shown
below.

Due to the call 'win_claim_idle_events(-1);' the static variable
'win__idle' will be set to -1.

Suppose we get an null event and enter the function 'win_processevent()'.
The automatic variable wimp_w w will be set to win__idle (is -1).

Below the 'switch (e->e)' the following statement appears:
        if (w==win__unknown_flag || win__find(w) == 0)

Normally the function 'win__find(w)' will return 0 when the parameter w
equals -1, and all unknow event processors are called.

*But* suppose we used a dialogbox somewhere before the above code, the
functions 'win_register_event_handler(d->w, 0, 0)' and win__discard(w)
are called due to dialog box disposing.

In the function 'win__discard(wimp_w w)' the statement:
        win__allwindows[i].w = DUD;
is used. The macro DUD equals to -1.

Now this -1 has nothing to do with the previous -1 used to flag no window
as a receiver of null events.

Now take a closer look at the function 'win__find(wimp_w w)'. We see
that the statements:
        if (win__allwindows[i].w == w) {
              return(&win__allwindows[i]);

compare the two -1's and 'win__find()' returns the pointer to the 'win_str'
of the previous disposed dialog box!

In most cases this bug will not appear, because the dialog box window
will be the last window in the win_str array. An attempt to call
'win__discard()' will decrease the variable 'win__lim' if the
element 'win__allwindows[win__lim-1].w == DUD'. But if the dialog box
window isn't in the last (win__lim) position the DUD element will
remain in the win_str array and can still be compared to the -1 from
the win__idle variable.

Solution: set the macro DUD to another negative value (-10?) and compile the
file 'win.c' again and link it to your code or call 'win_claim_idle_events()'
with another negative value as parameter!
'win__find()' now returns 0 and the 'unknown event processors' are called
as one would expect.


ferdinand.

P.S. In Holland we say: Je moet geen koeien met paarden verglijken.