[Libreoffice] va_start without va_end
Julien Nabet
serval2412 at yahoo.fr
Thu Aug 4 14:10:08 PDT 2011
Le 04/08/2011 10:33, Caolán McNamara a écrit :
> On Wed, 2011-08-03 at 23:56 +0200, Julien Nabet wrote:
>> Hello,
>>
>> In svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx, I
>> noticed the use of va_start without va_end.
>> I read it could create undefined behaviour, so I propose this simple patch.
>>
> ...
>> + va_end(pArgs);
>> }
>> }
>>
>> If it's ok, i can commit and push it on master.
> The va_end is tucked away hidden inside InitializeRanges_Impl in
> svl/source/items/nranges.cxx
>
> This looks rather ugly, it would be nicer to get the va_start and va_end
> closer together, e.g. move the va_end out of InitializeRanges_Impl and
> put it close to the two va_starts
Hello,
I had took a look at the called function but not at the "called called"
function. Sorry for having missed this.
So I did what you proposed, commited and pushed the patch on master.
I created a tracker for new check on cppcheck about va_start not in
pairs with va_end (ticket 2959)
I found other cases, this time I tried to find the called called...
1)
/libs-gui/i18npool/source/calendar/
calendar_gregorian.cxx 62 va_start(ap, pat);
59 static void debug_cal_msg(const char *pat, ...)
60 {
61 va_list ap;
62 va_start(ap, pat);
63 vfprintf(stderr, pat, ap);
64 }
I read that vfprintf didn't call automatically va_end
(http://www.cplusplus.com/reference/clibrary/cstdio/vfprintf/)
so I would add a va_end there
2)
/libs-core/sfx2/source/menu/
mnumgr.cxx 444 va_start(pArgs, pArg1);
439 sal_uInt16 SfxPopupMenuManager::Execute( const Point& rPoint,
Window* pWindow, const SfxPoolItem *pArg1, ... )
440 {
441 DBG_MEMTEST();
442
443 va_list pArgs;
444 va_start(pArgs, pArg1);
445
446 return (Execute( rPoint, pWindow, pArgs, pArg1 ));
447 }
which seems to call in the same file :
422 sal_uInt16 SfxPopupMenuManager::Execute( const Point& rPoint,
Window* pWindow, va_list pArgs, const SfxPoolItem *pArg1 )
423 {
424 DBG_MEMTEST();
425
426 PopupMenu* pPopMenu = ( (PopupMenu*)GetMenu()->GetSVMenu() );
427 pPopMenu->SetSelectHdl( LINK( this, SfxPopupMenuManager,
SelectHdl ) );
428 sal_uInt16 nId = pPopMenu->Execute( pWindow, rPoint );
429 pPopMenu->SetSelectHdl( Link() );
430
431 if ( nId )
432 GetBindings().GetDispatcher()->_Execute( nId,
SFX_CALLMODE_RECORD, pArgs, pArg1 );
433
434 return nId;
435 }
which seems to call in the file
/libs-core/sfx2/source/control/dispatch.cxx :
const SfxPoolItem* SfxDispatcher::_Execute
1381 (
1382 sal_uInt16 nSlot, // the Id of the executing
function
1383 SfxCallMode eCall, // SFX_CALLMODE_SYNCRHON,
..._ASYNCHRON or
1384 //..._SLOT
1385 va_list pVarArgs, // Parameter list from the
2nd parameter
1386 const SfxPoolItem* pArg1 // First parameter
1387 )
1388
1389 /* [Description]
1390
1391 Method to excecute a <SfxSlot>s over the Slot-Id.
1392
1393 [Return value]
1394
1395 const SfxPoolItem* Pointer to the SfxPoolItem valid to
the next run
1396 though the Message-Loop, which
contains the return
1397 value.
1398
1399 Or a NULL-Pointer, when the
function was not
1400 executed (for example canceled by
the user).
1401 */
1402
1403 {
1404 if ( IsLocked(nSlot) )
1405 return 0;
1406
1407 SfxShell *pShell = 0;
1408 const SfxSlot *pSlot = 0;
1409 if ( GetShellAndSlot_Impl( nSlot, &pShell, &pSlot, sal_False,
1410
SFX_CALLMODE_MODAL==(eCall&SFX_CALLMODE_MODAL) ) )
1411 {
1412 SfxAllItemSet aSet( pShell->GetPool() );
1413
1414 for ( const SfxPoolItem *pArg = pArg1;
1415 pArg;
1416 pArg = va_arg( pVarArgs, const SfxPoolItem* ) )
1417 MappedPut_Impl( aSet, *pArg );
1418
1419 SfxRequest aReq( nSlot, eCall, aSet );
1420 _Execute( *pShell, *pSlot, aReq, eCall );
1421 return aReq.GetReturnValue();
1422 }
1423 return 0;
1424 }
so I would add a va_end in SfxPopupMenuManager::Execute
3)
there are some cases (above all in win32 parts that I can't compile to
check patch) like this one :
/components/setup_native/source/win32/customactions/reg64/
reg64.cxx 77 va_start( args, pFormat );
inline void OutputDebugStringFormat( const wchar_t* pFormat, ... )
73 {
74 wchar_t buffer[1024];
75 va_list args;
76
77 va_start( args, pFormat );
78 StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
79 OutputDebugString( buffer );
80 }
I found nothing which tells if StringCchVPrintf calls automatically
va_end or not.
Since this function seems derived from Vprintf, I would add a va_end too.
Julien
More information about the LibreOffice
mailing list