| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| subject: | crazy iclui bug |
Hello all,
ICLUI BUG: the IFOnt Private Class IFontPrivateData does not initialize
the 'refs' member on copyConstructor. (at least in CTO<=304. not checked
in cto305. in windows version (VACPP/NT fixed, but in the sources shipped
in vacpp/NT in the __OS2__ part also NOT fixed).
effects: random traps in iclui when many fonts are used. (reason :
iprivatefontdata contains the elements referenced in IFont. and when refs
has a value < 0, the pointers are free'd but still used in IFont).
the copy constructor is used in
> IFont& IFont :: copyPrivate( )
> {
> if ( ppd->refCount() > 1 )
> {
> IFontPrivateData* newppd = new IFontPrivateData( *ppd );
and copyPrivate is used whenever something is modified in IFont.
eq:
> IFont& IFont :: setDirection( Direction lFontDir )
> {
> copyPrivate();
> switch (lFontDir) {
> case leftToRight:
problem in fixing this problem:
We are using CTO303, since CTO-GA is too buggy for us (a lot of the
problems i reported against VACPP GA are fixed in CTO303) and CTO305 is
again too buggy for us.
on the other side, there is no Source code available for CTO303. ICLUI
source is ONLY available for VACPP GA (CTS-GA) and CTO304 (== CTS304).
since IFonts are used inside ICLUI itself, we want a fix which fixes
the problem on EVERY usage of IFont. so, there are just 2 ways:
.) recompile source - No way
.) patch the dll.
ok, here's my analysis and the method for how to patch ICLUI DLL cppoou3.dll
to remove a VERY VERY CRITICAL OCL bug!
first take a look about the buggy copy constructor:
> IFontPrivateData::IFontPrivateData( const IFontPrivateData& fpd )
> {
> flClStyles = fpd.flClStyles;
> lClLCId = 0;
> lClFontDir = fpd.lClFontDir;
> pntClAngle = fpd.pntClAngle;
> pntClShear = fpd.pntClShear;
> fxClPointSize = fpd.fxClPointSize;
> fxClHeight = fpd.fxClHeight;
> fxClWidth = fpd.fxClWidth;
> plClCharWidths = 0;
as we can see the programmer of this source code does NOT have a good
understanding of C++. this gives us a chance for hacking. (thx IBM).
what we can see is, that the elements are initialized via ASSIGMENT and
not via INITIALIZATION. this means, that elements which are itself
classObjects are INITIALIZED via defaultConstructor and then
reassigned a value here. (but as we all know, there is no need to
think when we write code. iclui is fast enough .....).
so, lets take a look at IPrivateFontData of there is any member which is
a non standard type:
> class IFontPrivateData : public IBase {
> ....
> unsigned long
> flClStyles; 0
>
> struct _FONTMETRICS
> *pfontmetCl; 4
>
> struct _FATTRS
> *pfattrsCl; 8
>
> IPoint
> pntClAngle, 12 0x0c,0x10
> pntClShear; 20 0x14,0x18
>
> long
> *plClCharWidths, 28
> fxClPointSize, 32
> fxClHeight, 36
> fxClWidth, 40
> lClFontDir, 44
> lClLCId; 48 0x30
> unsigned long
> refs; 52 0x34 NOT INITALIZED
found it! IPoint pntClAngle and pntClShear.
next : IFont changed between VACPP-GA and CTC304 only (!) in the addition
of a new textWidth member function with a IBidi parameter. so, lets
compile ifont and lets generate an assmbler file to see whats going on:
epm: I:\ibmcppsrc\iocsrc\cppoou3 >cc -m -a /I..\include ifont.cpp
icc -Fd+ -Sm -Ss+ -Si+ -Q+ -Wall+cls-gnr-lan-par-ppt-vft-inl-ppc-use-
-W3 -Tl30 -Gm+ -Fa /I..\include ifont.cpp
when you compare the IFontPrivateData copy-constructor here (in the
generated .asm file) and in the cppoou3.dll you will see they are
equivalent!
so, lets take a look at the .asm code:
> ; 94 IFontPrivateData::IFontPrivateData( const IFontPrivateData& fpd )
> align 04h
>
> public __ct__16IFontPrivateDataFRC16IFontPrivateData
> __ct__16IFontPrivateDataFRC16IFontPrivateData proc
> push ebx
>
> ; 30 : coordCl1( 0 ), coordCl2( 0 )
> !!!!!! this is the default constructor of IPoint
> !!!!!! pntClAngle, 12 0x0c,0x10
> mov dword ptr [eax+0ch],0h
> mov dword ptr [eax+010h],0h
>
> ; 99
> !!!!!! ebx=edx+12
> lea ebx,[edx+0ch]
>
> !!!!!! this is the default constructor of IPoint
> !!!!!! pntClShear; 20 0x14,0x18
> ; 30 : coordCl1( 0 ), coordCl2( 0 )
> mov dword ptr [eax+014h],0h
> mov dword ptr [eax+018h],0h
>
>
> !!!!! so, as expected, the 2 default constructors for the 2 IPoint members
> !!!!! are called. the real initialization of the 2 ipoint members should
> !!!!! happen a bit later.
>
> ; 96 flClStyles = fpd.flClStyles;
> mov ecx,[edx]
> mov [eax],ecx
>
> ; 97 lClLCId = 0;
> mov dword ptr [eax+030h],0h
>
> ; 98 lClFontDir = fpd.lClFontDir;
> mov ecx,[edx+02ch]
>
> ; 94 IFontPrivateData::IFontPrivateData( const IFontPrivateData& fpd )
> push edi
>
> ; 98 lClFontDir = fpd.lClFontDir;
> mov [eax+02ch],ecx
>
> !!!!!
> !!!!! and here pntAngle is re-initialized via ass-operator
> !!!!! thx IBM that you are not initializing class members via
> !!!!! initLists ....
> !!!!! IFontPrivateData(xx) : a(xx_1), a(xx_2) , ... {}
> !!!!! result in constructors only
> !!!!! vs IFontPrivateData(xx) { a=xx_1; b=xx_2; ....}
> !!!!! result in def. constructors + assOperators
> !!!!!
>
> ; 99 pntClAngle = fpd.pntClAngle;
> lea ecx,[eax+0ch]
> mov edi,[ebx]
> mov [ecx],edi
> mov edi,[ebx+04h]
>
> !!!!! eax = &fbd.pntClShear
> ; 100 pntClShear = fpd.pntClShear;
> lea ebx,[edx+014h]
>
> ; 99 pntClAngle = fpd.pntClAngle;
> mov [ecx+04h],edi
>
> !!!!! ecx = &pntClShear
> ; 100 pntClShear = fpd.pntClShear;
> lea ecx,[eax+014h]
>
> ; 94 IFontPrivateData::IFontPrivateData( const IFontPrivateData& fpd )
> push esi
>
> !!!!! the same stuff as above. here we have the assigment Op
> !!!!! part for the 2nd IPoint
> ; 100 pntClShear = fpd.pntClShear;
> mov edi,[ebx]
> mov [ecx],edi
> mov edi,[ebx+04h]
> mov [ecx+04h],edi
>
> ; 101 fxClPointSize = fpd.fxClPointSize;
ok, so we only have to find this routine in the cppoou3.dll and then we
can patch it. we have enough place to play around, since all the following
4 statements are without effect:
> mov dword ptr [eax+0ch],0h
> mov dword ptr [eax+010h],0h
> mov dword ptr [eax+014h],0h
> mov dword ptr [eax+018h],0h
best is the patch the first one to
> mov dword ptr [eax+34h],0h
so, lets find the start of the code in the dll. since neither ipmd not
icc helps us really here (they don't display the hex values for
statement) i'm using microsSofts masm 6.0b for this.
lets write a mini .cpp file to generate the assembler file layout
and then write in the first 10 statements of the above code and let masm
generate a source listing. this looks like:
public func__Fv
0000 func__Fv proc
0000 53 push ebx
0001 C7 40 0C 00000000 mov dword ptr [eax+0ch],0h
0008 C7 40 10 00000000 mov dword ptr [eax+010h],0h
000F 8D 5A 0C lea ebx,[edx+0ch]
0012 C7 40 14 00000000 mov dword ptr [eax+014h],0h
0019 C7 40 18 00000000 mov dword ptr [eax+018h],0h
0020 8B 0A mov ecx,[edx]
0022 89 08 mov [eax],ecx
0024 C7 40 30 00000000 mov dword ptr [eax+030h],0h
002B C7 40 34 00000000 mov dword ptr [eax+034h],0h
0032 C3 ret
0033 func__Fv endp
0033 CODE32 ends
(xx.cpp == void func() { }, icc /Fa xx.cpp and then just insert the
asm statements. for assembling i've used: 'ml /Fl xx.asm'.
so, lets search for c7400c00000000c74010000000. (therefore i've used
an hex editor). this string is only once in the DLL. (at
decimal offset 702852). then chance 0c to 34 (which is the offset of
the refs member) and you are a lucky guy again.
WARPED!, Mario
--- Msgedsq/2 2.2e
* Origin: LC/32 Development Team-Vienna-Austria (2:310/14.11)SEEN-BY: 50/99 270/101 620/243 625/160 711/401 409 410 413 430 808 809 934 SEEN-BY: 711/955 712/407 515 624 628 713/317 800/1 @PATH: 310/14 1 24/999 888 396/1 270/101 712/515 711/808 934 |
|
| SOURCE: echomail via fidonet.ozzmosis.com | |
Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.