Bug #13
Updated by J. Templ over 10 years ago
The compiler ignores hidden pointer fields in base types of a record B when B is nested into another record C. This leads to an inconsistent type descriptor of C and thereby to memory corruption and a system crash.
Refers to CPC 1.7 rc5 change list number 19.
Marco Ciot:
> The affected module is DevCPT.
>
> The bug is very old. I guess it was there in the original Oberon Compiler written by N. Wirth, already. (And never discovered so far?!?) If this particular language construct is used, however, it leads to Heap Corruption.
Marco Ciot:
> Fixed excerpt from DevCPT:
<pre>
PROCEDURE OutRecurseBaseTypeForHdFlds (typ: Struct; adr: INTEGER);
BEGIN
IF typ.BaseTyp # NIL THEN OutRecurseBaseTypeForHdFlds(typ.BaseTyp, adr); END;
OutFlds(typ.link, adr, FALSE);
END OutRecurseBaseTypeForHdFlds;
PROCEDURE OutHdFld(typ: Struct; fld: Object; adr: INTEGER);
VAR i, j, n: INTEGER; btyp: Struct; debugNow: BOOLEAN;
BEGIN
IF typ.comp = Record THEN
IF typ.BaseTyp # NIL THEN OutRecurseBaseTypeForHdFlds(typ.BaseTyp, adr); END;
OutFlds(typ.link, adr, FALSE);
</pre>
> Additionally the finger printing needs to be fixed, as well:
<pre>
PROCEDURE FPrintStr*(typ: Struct);
VAR f, c: SHORTINT; btyp: Struct; strobj, bstrobj: Object; pbfp, pvfp: INTEGER;
PROCEDURE ^FPrintFlds(fld: Object; adr: INTEGER; visible: BOOLEAN);
PROCEDURE FPrintRecurseBaseTypeForHdFlds (typ: Struct; adr: INTEGER);
BEGIN
IF typ.BaseTyp # NIL THEN FPrintRecurseBaseTypeForHdFlds(typ.BaseTyp, adr); END;
FPrintFlds(typ.link, adr, FALSE);
END FPrintRecurseBaseTypeForHdFlds;
PROCEDURE FPrintHdFld(typ: Struct; fld: Object; adr: INTEGER); (* modifies pvfp only *)
VAR i, j, n: INTEGER; btyp: Struct;
BEGIN
IF typ.comp = Record THEN
IF typ.BaseTyp # NIL THEN FPrintRecurseBaseTypeForHdFlds(typ.BaseTyp, adr); END;
FPrintFlds(typ.link, adr, FALSE);
</pre>
Josef Templ wrote:
> The names OutRecurseBaseTypeForHdFlds and FPrintRecurseBaseTypeForHdFlds
> are instructive for reviewing purposes.
> The names of the new procedures are inappropriate.
> Use *OutHdBaseFlds* and *FPrintHdBaseFlds*.
> It is hard to imagine that any other name would be more 'natural'
> and the currently used names are certainly not fitting with the existing names.