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