Ticket #9950: 0001-DownloadManager-Fix-SEGV-after-timeout.patch

File 0001-DownloadManager-Fix-SEGV-after-timeout.patch, 3.9 KB (added by Lawrence Rust <lvr@…>, 13 years ago)
  • mythtv/libs/libmythbase/mythdownloadmanager.cpp

    From a6b3d0b9cada67d3315c5320d426141310ac5f0a Mon Sep 17 00:00:00 2001
    From: Lawrence Rust <lvr@softsystem.co.uk>
    Date: Wed, 27 Jul 2011 15:34:53 +0200
    Subject: [PATCH] DownloadManager: Fix SEGV after timeout
    
    1. Fix a SEGV that can occur if a download times out.  If a caller makes
    a synchronous call then downloadNow will timeout after 10 seconds but
    downloadFinished, which is a slot, can be called after control has returned
    to the caller and the QByteArray data buffer has been deallocated.
    
    2. Allow the caller to set their own User-Agent header.
    
    3. Provide better error reporting.
    
    Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
    ---
     mythtv/libs/libmythbase/mythdownloadmanager.cpp |   20 ++++++++++++--------
     1 files changed, 12 insertions(+), 8 deletions(-)
    
    diff --git a/mythtv/libs/libmythbase/mythdownloadmanager.cpp b/mythtv/libs/libmythbase/mythdownloadmanager.cpp
    index 2d3d645..2e24806 100644
    a b void MythDownloadManager::downloadQNetworkRequest(MythDownloadInfo *dlInfo) 
    608608        request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
    609609                             QNetworkRequest::PreferCache);
    610610
    611     request.setRawHeader("User-Agent",
    612                          "MythDownloadManager v" MYTH_BINARY_VERSION);
     611    if (!request.hasRawHeader("User-Agent"))
     612        request.setRawHeader("User-Agent",
     613                             "MythDownloadManager v" MYTH_BINARY_VERSION);
    613614
    614615    if (dlInfo->m_post)
    615616        dlInfo->m_reply = m_manager->post(request, *dlInfo->m_data);
    bool MythDownloadManager::downloadNow(MythDownloadInfo *dlInfo, bool deleteInfo) 
    666667    if (!dlInfo->m_done)
    667668    {
    668669        dlInfo->m_syncMode = false; // Let downloadFinished() cleanup for us
     670        dlInfo->m_data = 0; // !! Otherwise downloadFinished will write to this
    669671        if ((dlInfo->m_reply) &&
    670672            (dlInfo->m_errorCode == QNetworkReply::NoError))
    671673            dlInfo->m_reply->abort();
    void MythDownloadManager::downloadError(QNetworkReply::NetworkError errorCode) 
    713715{
    714716    QNetworkReply *reply = (QNetworkReply*)sender();
    715717
    716     LOG(VB_FILE, LOG_DEBUG, LOC + QString("downloadError(%1) (for reply %2)")
    717                     .arg(errorCode).arg((long long)reply));
     718    // NB The errorString includes the URL
     719    LOG(VB_FILE, LOG_DEBUG, LOC + QString("downloadError %1 ")
     720                    .arg(errorCode) + reply->errorString() );
    718721
    719722    QMutexLocker locker(m_infoLock);
    720723    if (!m_downloadReplies.contains(reply))
    void MythDownloadManager::downloadFinished(MythDownloadInfo *dlInfo) 
    803806        if (dlInfo->m_preferCache)
    804807            request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
    805808                                 QNetworkRequest::PreferCache);
    806         request.setRawHeader("User-Agent",
    807                              "MythDownloadManager v" MYTH_BINARY_VERSION);
     809        if (!request.hasRawHeader("User-Agent"))
     810            request.setRawHeader("User-Agent",
     811                                 "MythDownloadManager v" MYTH_BINARY_VERSION);
    808812
    809813        if (dlInfo->m_post)
    810814            dlInfo->m_reply = m_manager->post(request, *dlInfo->m_data);
    void MythDownloadManager::downloadFinished(MythDownloadInfo *dlInfo) 
    891895                args << dlInfo->m_url;
    892896                args << dlInfo->m_outFile;
    893897                args << QString::number(dlInfo->m_bytesTotal);
    894                 args << QString();  // placeholder for error string
    895                 args << QString::number((int)dlInfo->m_errorCode);
     898                args << (reply ? reply->errorString() : QString());  // placeholder for error string
     899                args << QString::number((int)(reply ? reply->error() : dlInfo->m_errorCode));
    896900
    897901                QCoreApplication::postEvent(dlInfo->m_caller,
    898902                    new MythEvent("DOWNLOAD_FILE FINISHED", args));