On Fri, 22 Jan 2010, Mindaugas Kavaliauskas wrote:

Hi,

> I'm do not follow xHarbour changes any more,

It's quite old code which I still remember,

> but I guess you are talking about hb_itemPutCL():
> 620           if( szText == pItem->item.asString.value )
> 621           {
> 622             pItem->item.asString.value[ ulLen ] = '\0';
> 623             pItem->item.asString.length = ulLen;
> 624
> 625             return pItem;
> 626           }

I've just check current xHarbour code and also next lines:
627           else if( szText > pItem->item.asString.value && szText <= 
pItem->item.asString.value + pItem->item.asString.length )
...
634           }
checks for overlapped regions.

Anyhow it's good to refresh mind sometimes ;-).
I forgot that few years ago I updated Harbour code to call hb_xgrab()
before hb_itemClear() in hb_itemPutC[L]() so it's also safe to make:
   hb_storc( hb_parc( 1 ), 1 );
anyhow as I said before it helps only in this particular case and the
problem can be still exploited by accessing different items.

> >   hb_storc( pszFile, 1 );
> >is safe.
> I guess because in hb_itemPutC() (in Harbour) code:
>  szText = ( char * ) hb_xmemcpy( hb_xgrab( ulAlloc ), szText, ulAlloc );
> is executed before:
>   hb_itemClear( pItem );

Yes, I added it intentionally and I forgot about it. It means that we
can simplify NETIO_DECODE() code and only have to keep strict order
of hb_stor*() calls. I'll commit it.

> What about code:
>    cI := "x127.0.0.1:2941:password:filename"
>    cI := SUBSTR(cI, 2) // Let's create dynamic string instead of PCODE
>    NETIO_DECODE(cI,,,,@cI) // I want to reuse cI value for password
> Is this code safe in current version of NETIO_DECODE()?

In this case nothing wrong because number of reference counters to cI
is 2: 1 for the cI local variable and 1 for the 1-st netio_decode()
parameter so assign to @cI does not change it.
But the problem can be exploited if you change the last line of your
code to:
    NETIO_DECODE(@cI,,,,@cI)
in such case the reference counter for the string item stored in cI is 1
and any assignment to the 1-st or the 5-th parameter can damage both
pointers previously returned by hb_parc( 1 ) and hb_parc( 5 ).

> >It can be resolved in two ways. One of them I used in new string API
> >I recently added where such problems does not exist. Just simply it's
> >enough to call:
> >   hb_strfree( hFullName );
> >after setting all parameters.
> What is another way?

If not programmer locks and unlock the memory area then it has to be done
by system. In the second version HVM has to lock the pointers returned
by hb_parc*() functions until some arbitrary point is reach, i.e.
until function returns. It means that when you call hb_parc( <n> )
1-st time then HVM creates internally hString reference just like
hb_parstr*() functions and attach it to function frame. When function
frame is removed then all such pointers are automatically freed so
each memory buffers returned by hb_parc*() functions are valid for
whole function life.

> Sometimes I understand, the things that always seemed simple are not such.

It's simple but programmers have to remember that functions like
hb_parc*() or hb_arrayGetItemPtr() return pointers to area which can
be damage by other function calls. Such API does not give any pointer
protection so it's danger.

best regards,
Przemek
_______________________________________________
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to