#872: crash in bitfield code when loading resume files
This commit is contained in:
parent
f467beedb5
commit
c8c84d6bd1
|
@ -28,6 +28,7 @@ libtransmission_a_SOURCES = \
|
|||
ptrarray.c \
|
||||
publish.c \
|
||||
ratecontrol.c \
|
||||
resume.c \
|
||||
session.c \
|
||||
stats.c \
|
||||
torrent.c \
|
||||
|
@ -64,6 +65,7 @@ noinst_HEADERS = \
|
|||
ptrarray.h \
|
||||
publish.h \
|
||||
ratecontrol.h \
|
||||
resume.h \
|
||||
session.h \
|
||||
stats.h \
|
||||
torrent.h \
|
||||
|
|
|
@ -237,19 +237,20 @@ const tr_bitfield * tr_cpBlockBitfield( const tr_completion * cp )
|
|||
return cp->blockBitfield;
|
||||
}
|
||||
|
||||
void
|
||||
tr_errno
|
||||
tr_cpBlockBitfieldSet( tr_completion * cp, tr_bitfield * bitfield )
|
||||
{
|
||||
tr_block_index_t i;
|
||||
|
||||
assert( cp != NULL );
|
||||
assert( bitfield != NULL );
|
||||
if( !cp || !bitfield || ( bitfield->len != cp->blockBitfield->len ) )
|
||||
return TR_ERROR_ASSERT;
|
||||
|
||||
tr_cpReset( cp );
|
||||
|
||||
for( i=0; i < cp->tor->blockCount; ++i )
|
||||
if( tr_bitfieldHas( bitfield, i ) )
|
||||
tr_cpBlockAdd( cp, i );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
|
|
|
@ -53,7 +53,7 @@ void tr_cpPieceRem( tr_completion *, tr_piece_index_t piece );
|
|||
/* Blocks */
|
||||
int tr_cpBlockIsComplete( const tr_completion *, tr_block_index_t block );
|
||||
void tr_cpBlockAdd( tr_completion *, tr_block_index_t block );
|
||||
void tr_cpBlockBitfieldSet( tr_completion *, struct tr_bitfield * );
|
||||
tr_errno tr_cpBlockBitfieldSet( tr_completion *, struct tr_bitfield * );
|
||||
float tr_cpPercentBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece );
|
||||
int tr_cpMissingBlocksInPiece( const tr_completion * cp, tr_piece_index_t piece );
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "fastresume.h"
|
||||
#include "peer-mgr.h"
|
||||
#include "platform.h"
|
||||
#include "resume.h" /* TR_FR_ bitwise enum */
|
||||
#include "torrent.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -115,7 +116,7 @@ enum
|
|||
#define FR_MTIME_LEN( t ) \
|
||||
( sizeof(tr_time_t) * (t)->info.fileCount )
|
||||
#define FR_BLOCK_BITFIELD_LEN( t ) \
|
||||
( ( (t)->blockCount + 7 ) / 8 )
|
||||
( ( (t)->blockCount + 7u ) / 8u )
|
||||
#define FR_PROGRESS_LEN( t ) \
|
||||
( FR_MTIME_LEN( t ) + FR_BLOCK_BITFIELD_LEN( t ) )
|
||||
#define FR_SPEED_LEN (2 * (sizeof(uint16_t) + sizeof(uint8_t) ) )
|
||||
|
@ -426,9 +427,12 @@ parseProgress( tr_torrent * tor,
|
|||
memset( &bitfield, 0, sizeof bitfield );
|
||||
bitfield.len = FR_BLOCK_BITFIELD_LEN( tor );
|
||||
bitfield.bits = (uint8_t*) walk;
|
||||
tr_cpBlockBitfieldSet( tor->completion, &bitfield );
|
||||
|
||||
ret = TR_FR_PROGRESS;
|
||||
if( !tr_cpBlockBitfieldSet( tor->completion, &bitfield ) )
|
||||
ret = TR_FR_PROGRESS;
|
||||
else {
|
||||
tr_torrentUncheck( tor );
|
||||
tr_tordbg( tor, "Torrent needs to be verified" );
|
||||
}
|
||||
}
|
||||
|
||||
/* the files whose mtimes are wrong,
|
||||
|
|
|
@ -27,20 +27,6 @@
|
|||
|
||||
void tr_fastResumeSave( const tr_torrent * tor );
|
||||
|
||||
enum
|
||||
{
|
||||
TR_FR_DOWNLOADED = (1<<0),
|
||||
TR_FR_UPLOADED = (1<<1),
|
||||
TR_FR_CORRUPT = (1<<2),
|
||||
TR_FR_PEERS = (1<<3),
|
||||
TR_FR_PROGRESS = (1<<4),
|
||||
TR_FR_PRIORITY = (1<<5),
|
||||
TR_FR_SPEEDLIMIT = (1<<6),
|
||||
TR_FR_RUN = (1<<7),
|
||||
TR_FR_DESTINATION = (1<<8),
|
||||
TR_FR_MAX_PEERS = (1<<9)
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a bitwise-or'ed set of the data loaded from fastresume
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* unlink */
|
||||
|
||||
#include "transmission.h"
|
||||
#include "fastresume.h"
|
||||
#include "platform.h" /* tr_getResumeDir */
|
||||
#include "resume.h"
|
||||
#include "torrent.h"
|
||||
#include "utils.h" /* tr_buildPath */
|
||||
|
||||
static void
|
||||
getResumeFilename( char * buf, size_t buflen, const tr_torrent * tor )
|
||||
{
|
||||
const char * dir = tr_getResumeDir( tor->handle );
|
||||
char base[4096];
|
||||
snprintf( base, sizeof( base ), "%s.%10.10s.resume", tor->info.name, tor->info.hashString );
|
||||
tr_buildPath( buf, buflen, dir, base, NULL );
|
||||
fprintf( stderr, "filename is [%s]\n", buf );
|
||||
}
|
||||
|
||||
uint64_t
|
||||
tr_torrentLoadResume( tr_torrent * tor,
|
||||
uint64_t fieldsToLoad,
|
||||
const tr_ctor * ctor )
|
||||
{
|
||||
uint64_t fieldsLoaded = 0;
|
||||
uint8_t * content;
|
||||
size_t contentLen;
|
||||
char filename[MAX_PATH_LENGTH];
|
||||
|
||||
getResumeFilename( filename, sizeof( filename ), tor );
|
||||
content = tr_loadFile( filename, &contentLen );
|
||||
if( content )
|
||||
{
|
||||
tr_free( content );
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldsLoaded = tr_fastResumeLoad( tor, fieldsToLoad, ctor );
|
||||
}
|
||||
|
||||
return fieldsLoaded;
|
||||
}
|
||||
|
||||
void
|
||||
tr_torrentSaveResume( const tr_torrent * tor )
|
||||
{
|
||||
char filename[MAX_PATH_LENGTH];
|
||||
getResumeFilename( filename, sizeof( filename ), tor );
|
||||
|
||||
/* (temporary) */
|
||||
tr_fastResumeSave( tor );
|
||||
}
|
||||
|
||||
void
|
||||
tr_torrentRemoveResume( const tr_torrent * tor )
|
||||
{
|
||||
char filename[MAX_PATH_LENGTH];
|
||||
getResumeFilename( filename, sizeof( filename ), tor );
|
||||
unlink( filename );
|
||||
tr_fastResumeRemove( tor );
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#ifndef TR_RESUME_H
|
||||
#define TR_RESUME_H
|
||||
|
||||
enum
|
||||
{
|
||||
TR_FR_DOWNLOADED = (1<<0),
|
||||
TR_FR_UPLOADED = (1<<1),
|
||||
TR_FR_CORRUPT = (1<<2),
|
||||
TR_FR_PEERS = (1<<3),
|
||||
TR_FR_PROGRESS = (1<<4),
|
||||
TR_FR_PRIORITY = (1<<5),
|
||||
TR_FR_SPEEDLIMIT = (1<<6),
|
||||
TR_FR_RUN = (1<<7),
|
||||
TR_FR_DESTINATION = (1<<8),
|
||||
TR_FR_MAX_PEERS = (1<<9)
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a bitwise-or'ed set of the loaded resume data
|
||||
*/
|
||||
uint64_t tr_torrentLoadResume( tr_torrent * tor,
|
||||
uint64_t fieldsToLoad,
|
||||
const tr_ctor * ctor );
|
||||
|
||||
void tr_torrentSaveResume( const tr_torrent * tor );
|
||||
|
||||
void tr_torrentRemoveResume( const tr_torrent * tor );
|
||||
|
||||
#endif
|
|
@ -29,7 +29,7 @@
|
|||
#include "bencode.h"
|
||||
#include "completion.h"
|
||||
#include "crypto.h" /* for tr_sha1 */
|
||||
#include "fastresume.h"
|
||||
#include "resume.h"
|
||||
#include "fdlimit.h" /* tr_fdFileClose */
|
||||
#include "metainfo.h"
|
||||
#include "peer-mgr.h"
|
||||
|
@ -353,7 +353,7 @@ torrentRealInit( tr_handle * h,
|
|||
|
||||
tor->checkedPieces = tr_bitfieldNew( tor->info.pieceCount );
|
||||
tr_torrentUncheck( tor );
|
||||
loaded = tr_fastResumeLoad( tor, ~0, ctor );
|
||||
loaded = tr_torrentLoadResume( tor, ~0, ctor );
|
||||
|
||||
doStart = tor->isRunning;
|
||||
tor->isRunning = 0;
|
||||
|
@ -457,16 +457,6 @@ tr_torrentNew( tr_handle * handle,
|
|||
return tor;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
static void
|
||||
saveFastResumeNow( tr_torrent * tor )
|
||||
{
|
||||
tr_fastResumeSave( tor );
|
||||
}
|
||||
|
||||
/**
|
||||
***
|
||||
**/
|
||||
|
@ -476,7 +466,7 @@ tr_torrentSetFolder( tr_torrent * tor, const char * path )
|
|||
{
|
||||
tr_free( tor->destination );
|
||||
tor->destination = tr_strdup( path );
|
||||
saveFastResumeNow( tor );
|
||||
tr_torrentSaveResume( tor );
|
||||
}
|
||||
|
||||
const char*
|
||||
|
@ -824,7 +814,7 @@ tr_torrentRemoveSaved( tr_torrent * tor )
|
|||
{
|
||||
tr_metainfoRemoveSaved( tor->handle, tor->info.hashString );
|
||||
|
||||
tr_fastResumeRemove( tor );
|
||||
tr_torrentRemoveResume( tor );
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -921,7 +911,7 @@ checkAndStartImpl( void * vtor )
|
|||
*tor->errorString = '\0';
|
||||
tr_torrentResetTransferStats( tor );
|
||||
tor->cpStatus = tr_cpGetStatus( tor->completion );
|
||||
saveFastResumeNow( tor );
|
||||
tr_torrentSaveResume( tor );
|
||||
tor->startDate = tr_date( );
|
||||
tr_trackerStart( tor->tracker );
|
||||
tr_peerMgrStartTorrent( tor->handle->peerMgr, tor->info.hash );
|
||||
|
@ -942,7 +932,7 @@ tr_torrentStart( tr_torrent * tor )
|
|||
|
||||
if( !tor->isRunning )
|
||||
{
|
||||
tr_fastResumeLoad( tor, TR_FR_PROGRESS, NULL );
|
||||
tr_torrentLoadResume( tor, TR_FR_PROGRESS, NULL );
|
||||
tor->isRunning = 1;
|
||||
tr_verifyAdd( tor, checkAndStartCB );
|
||||
}
|
||||
|
@ -999,7 +989,7 @@ tr_torrentStop( tr_torrent * tor )
|
|||
tr_globalLock( tor->handle );
|
||||
|
||||
if( !tor->isDeleting )
|
||||
saveFastResumeNow( tor );
|
||||
tr_torrentSaveResume( tor );
|
||||
tor->isRunning = 0;
|
||||
tr_runInEventThread( tor->handle, stopTorrent, tor );
|
||||
|
||||
|
@ -1010,7 +1000,7 @@ static void
|
|||
closeTorrent( void * vtor )
|
||||
{
|
||||
tr_torrent * tor = vtor;
|
||||
saveFastResumeNow( tor );
|
||||
tr_torrentSaveResume( tor );
|
||||
tor->isRunning = 0;
|
||||
stopTorrent( tor );
|
||||
if( tor->isDeleting )
|
||||
|
@ -1112,7 +1102,7 @@ tr_torrentRecheckCompleteness( tr_torrent * tor )
|
|||
if( recentChange && ( cpStatus == TR_CP_COMPLETE ) )
|
||||
tr_trackerCompleted( tor->tracker );
|
||||
|
||||
saveFastResumeNow( tor );
|
||||
tr_torrentSaveResume( tor );
|
||||
}
|
||||
|
||||
tr_torrentUnlock( tor );
|
||||
|
@ -1158,7 +1148,7 @@ tr_torrentSetFilePriorities( tr_torrent * tor,
|
|||
for( i=0; i<fileCount; ++i )
|
||||
tr_torrentInitFilePriority( tor, files[i], priority );
|
||||
|
||||
saveFastResumeNow( tor );
|
||||
tr_torrentSaveResume( tor );
|
||||
tr_torrentUnlock( tor );
|
||||
}
|
||||
|
||||
|
@ -1285,7 +1275,7 @@ tr_torrentSetFileDLs ( tr_torrent * tor,
|
|||
{
|
||||
tr_torrentLock( tor );
|
||||
tr_torrentInitFileDLs( tor, files, fileCount, doDownload );
|
||||
saveFastResumeNow( tor );
|
||||
tr_torrentSaveResume( tor );
|
||||
tr_torrentUnlock( tor );
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "transmission.h"
|
||||
#include "completion.h"
|
||||
#include "fastresume.h" /* tr_fastResumeSave() */
|
||||
#include "resume.h" /* tr_torrentSaveResume() */
|
||||
#include "inout.h"
|
||||
#include "list.h"
|
||||
#include "platform.h"
|
||||
|
@ -133,7 +133,7 @@ verifyThreadFunc( void * unused UNUSED )
|
|||
|
||||
if( !stopCurrent )
|
||||
{
|
||||
tr_fastResumeSave( tor );
|
||||
tr_torrentSaveResume( tor );
|
||||
fireCheckDone( tor, currentNode.verify_done_cb );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue