Pointer validity checking defectsg

From: Erik Hovland <erik@hovland.org>

1. player_ctx is dereferenced many times before it is checked in this
   conditional. If player_ctx is going to be checked in this function
   it likely should be the first thing doneg

2. New set of ringBuffer checking. Plus an ic check

3. mon needs to be checked before dereferencingg

4. rotor checking

5. FiltChain needs checking

6. return if _rtsp_client is invalid, that way it isn't
   dereferenced a few lines laterg

7. Check m_priv

8. Check mctx before hitting its locksg

9. Calling SetErrored on ctx will dereference ctxg

10. Assign pointer from GetSet() so that we don't call GetSet twice

11. Check mctx againg

12. Don't need to check mctx now since we did it earlier

13. Check actx

14. Check validity of osd

15. Another mctx check

16. And another time where we can remove a check because we now do it
    earlier

17. osd checks

18. Check frame

19. Check m_ctx

20. vsz_tmp_buf will be dereferenced by ShutdownVideoResize so move the
    check up

21. Remove later check
---

 mythtv/libs/libmythtv/NuppelVideoPlayer.cpp        |    2 -
 mythtv/libs/libmythtv/avformatdecoder.cpp          |    6 +-
 .../libs/libmythtv/channelscan/channelscanner.cpp  |    2 -
 mythtv/libs/libmythtv/dvbsignalmonitor.cpp         |    2 +
 mythtv/libs/libmythtv/filtermanager.cpp            |    2 -
 mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp      |    1 
 mythtv/libs/libmythtv/linuxfirewiredevice.cpp      |    3 +
 mythtv/libs/libmythtv/tv_play.cpp                  |   54 +++++++++++++-------
 mythtv/libs/libmythtv/util-vdpau.cpp               |   23 +++++----
 mythtv/libs/libmythtv/videoout_vdpau.cpp           |   18 +++++--
 mythtv/libs/libmythtv/videooutbase.cpp             |    4 +
 11 files changed, 76 insertions(+), 41 deletions(-)


diff --git a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp b/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
index 9f31189..a136702 100644
--- a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
+++ b/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
@@ -4742,7 +4742,7 @@ bool NuppelVideoPlayer::IsNearEnd(long long margin) const
 
     framesRead = GetDecoder()->GetFramesRead();
 
-    if (player_ctx && !player_ctx->IsPIP() &&
+    if (!player_ctx->IsPIP() &&
         player_ctx->GetState() == kState_WatchingPreRecorded)
     {
         framesLeft = margin;
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 06350da..56046de 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -1175,7 +1175,7 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
 
     float aspect_ratio = 0.0;
 
-    if (ringBuffer->isDVD())
+    if (ringBuffer && ringBuffer->isDVD())
         directrendering = false;
 
     if (selectedStream)
@@ -1569,7 +1569,7 @@ int AvFormatDecoder::ScanStreams(bool novideo)
     map<int,uint> lang_sub_cnt;
     map<int,uint> lang_aud_cnt;
 
-    if (ringBuffer->isDVD() &&
+    if (ringBuffer && ringBuffer->isDVD() &&
         ringBuffer->DVD()->AudioStreamsChanged())
     {
         ringBuffer->DVD()->AudioStreamsChanged(false);
@@ -4212,7 +4212,7 @@ bool AvFormatDecoder::SetupAudioStream(void)
     AudioInfo old_out = audioOut;
     bool using_passthru = false;
 
-    if ((currentTrack[kTrackTypeAudio] >= 0) &&
+    if ((currentTrack[kTrackTypeAudio] >= 0) && ic &&
         (selectedTrack[kTrackTypeAudio].av_stream_index <=
          (int) ic->nb_streams) &&
         (curstream = ic->streams[selectedTrack[kTrackTypeAudio]
diff --git a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
index 0ecb376..9b05470 100644
--- a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
+++ b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
@@ -416,7 +416,7 @@ void ChannelScanner::PreScanCommon(
 
 #ifdef USING_DVB
     dvbm = sigmonScanner->GetDVBSignalMonitor();
-    if (dvbm)
+    if (dvbm && mon)
         using_rotor = mon->HasFlags(SignalMonitor::kDVBSigMon_WaitForPos);
 #endif // USING_DVB
 
diff --git a/mythtv/libs/libmythtv/dvbsignalmonitor.cpp b/mythtv/libs/libmythtv/dvbsignalmonitor.cpp
index c2742b7..d699c92 100644
--- a/mythtv/libs/libmythtv/dvbsignalmonitor.cpp
+++ b/mythtv/libs/libmythtv/dvbsignalmonitor.cpp
@@ -129,6 +129,8 @@ void DVBSignalMonitor::GetRotorStatus(bool &was_moving, bool &is_moving)
         return;
 
     const DiSEqCDevRotor *rotor = dvbchannel->GetRotor();
+    if (!rotor)
+        return;
 
     QMutexLocker locker(&statusLock);
     was_moving = rotorPosition.GetValue() < 100;
diff --git a/mythtv/libs/libmythtv/filtermanager.cpp b/mythtv/libs/libmythtv/filtermanager.cpp
index b4e5dae..db3b670 100644
--- a/mythtv/libs/libmythtv/filtermanager.cpp
+++ b/mythtv/libs/libmythtv/filtermanager.cpp
@@ -401,7 +401,7 @@ FilterChain *FilterManager::LoadFilters(QString Filters,
             break;
         }
 
-        if (NewFilt->filter)
+        if (NewFilt->filter && FiltChain)
         {
             FiltChain->Append(NewFilt);
         }
diff --git a/mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp b/mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp
index f8ed4b1..f34d05e 100644
--- a/mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp
+++ b/mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp
@@ -107,6 +107,7 @@ bool IPTVFeederRTSP::Open(const QString &url)
                 QString("Failed to create RTSP client: %1")
                 .arg(_live_env->getResultMsg()));
         FreeEnv();
+        return false;
     }
 
     // Setup URL for the current session
diff --git a/mythtv/libs/libmythtv/linuxfirewiredevice.cpp b/mythtv/libs/libmythtv/linuxfirewiredevice.cpp
index 05ebc93..7da7395 100644
--- a/mythtv/libs/libmythtv/linuxfirewiredevice.cpp
+++ b/mythtv/libs/libmythtv/linuxfirewiredevice.cpp
@@ -984,6 +984,9 @@ LinuxAVCInfo *LinuxFirewireDevice::GetInfoPtr(void)
 
 const LinuxAVCInfo *LinuxFirewireDevice::GetInfoPtr(void) const
 {
+    if (!m_priv)
+        return NULL;
+
     avcinfo_list_t::iterator it = m_priv->devices.find(m_guid);
     return (it == m_priv->devices.end()) ? NULL : *it;
 }
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp
index bb89a83..444aaa7 100644
--- a/mythtv/libs/libmythtv/tv_play.cpp
+++ b/mythtv/libs/libmythtv/tv_play.cpp
@@ -348,10 +348,14 @@ bool TV::StartTV(ProgramInfo *tvrec, bool startInGuide,
         const PlayerContext *mctx =
             tv->GetPlayerReadLock(0, __FILE__, __LINE__);
         quitAll = tv->wantsToQuit || (mctx && mctx->errored);
-        mctx->LockDeleteNVP(__FILE__, __LINE__);
-        if (mctx->nvp && mctx->nvp->IsErrored())
-            nvpError = mctx->nvp->GetError();
-        mctx->UnlockDeleteNVP(__FILE__, __LINE__);
+        if (mctx)
+        {
+            mctx->LockDeleteNVP(__FILE__, __LINE__);
+            if (mctx->nvp && mctx->nvp->IsErrored())
+                nvpError = mctx->nvp->GetError();
+
+            mctx->UnlockDeleteNVP(__FILE__, __LINE__);
+        }
         tv->ReturnPlayerLock(mctx);
     }
 
@@ -2334,7 +2338,6 @@ void TV::timerEvent(QTimerEvent *te)
         if (!ok || !pbinfo)
         {
             VERBOSE(VB_IMPORTANT, LOC_ERR + "lost contact with backend");
-            SetErrored(ctx);
         }
 
         ReturnPlayerLock(mctx);
@@ -2690,8 +2693,9 @@ void TV::timerEvent(QTimerEvent *te)
     {
         PlayerContext *actx = GetPlayerReadLock(-1, __FILE__, __LINE__);
         OSD *osd = GetOSDLock(actx);
-        if (osd && osd->GetSet("status") &&
-            osd->GetSet("status")->Displaying() &&
+        OSDSet *osdset = NULL;
+        if (osd && (osdset = osd->GetSet("status")) &&
+            osdset->Displaying() &&
             (StateIsLiveTV(actx->GetState()) ||
              StateIsPlaying(actx->GetState())))
         {
@@ -2720,6 +2724,8 @@ void TV::timerEvent(QTimerEvent *te)
     {
         bool error = false;
         PlayerContext *mctx = GetPlayerReadLock(0, __FILE__, __LINE__);
+        if (!mctx)
+            return;
 
         if (mctx->IsNVPErrored())
         {
@@ -2747,7 +2753,7 @@ void TV::timerEvent(QTimerEvent *te)
             error = true;
         }
 
-        for (uint i = 0; mctx && (i < player.size()); i++)
+        for (uint i = 0; i < player.size(); i++)
         {
             PlayerContext *ctx = GetPlayer(mctx, i);
             if (error || ctx->IsErrored())
@@ -3141,7 +3147,7 @@ void TV::HandleSpeedChangeTimerEvent(void)
         update_msg |= ctx->HandleNVPSpeedChangeEOF() && (ctx == actx);
     }
 
-    if (update_msg)
+    if (actx && update_msg)
     {
         UpdateOSDSeekMessage(actx, actx->GetPlayMessage(),
                              osd_general_timeout);
@@ -7215,16 +7221,19 @@ void TV::UpdateOSDSignal(const PlayerContext *ctx, const QStringList &strlist)
     else if (!msg.isEmpty())
         sigDesc = msg;
 
+    infoMap["description"] = sigDesc;
     //osd->ClearAllText("signal_info");
     //osd->SetText("signal_info", infoMap, -1);
 
     osd = GetOSDLock(ctx);
-    osd->ClearAllText("channel_number");
-    osd->SetText("channel_number", infoMap, osd_prog_info_timeout);
+    if (osd)
+    {
+        osd->ClearAllText("channel_number");
+        osd->SetText("channel_number", infoMap, osd_prog_info_timeout);
 
-    infoMap["description"] = sigDesc;
-    osd->ClearAllText("program_info");
-    osd->SetText("program_info", infoMap, osd_prog_info_timeout);
+        osd->ClearAllText("program_info");
+        osd->SetText("program_info", infoMap, osd_prog_info_timeout);
+    }
     ReturnOSDLock(ctx, osd);
 
     ctx->lastSignalMsg.clear();
@@ -8332,13 +8341,16 @@ void TV::customEvent(QEvent *e)
                 << " haslater: " << haslater);
 
         PlayerContext *mctx = GetPlayerReadLock(0, __FILE__, __LINE__);
+        if (!mctx)
+            return;
+
         if (mctx->recorder && cardnum == mctx->GetCardID())
         {
             AskAllowRecording(mctx, me->ExtraDataList(),
                               timeuntil, hasrec, haslater);
         }
 
-        for (uint i = 1; mctx && (i < player.size()); i++)
+        for (uint i = 1; i < player.size(); i++)
         {
             PlayerContext *ctx = GetPlayer(mctx, i);
             if (ctx->recorder && ctx->GetCardID() == cardnum)
@@ -10512,7 +10524,9 @@ void TV::ToggleAutoExpire(PlayerContext *ctx)
         if (ctx->CalcNVPSliderPosition(posInfo))
         {
             OSD *osd = GetOSDLock(ctx);
-            osd->ShowStatus(posInfo, false, desc, 1);
+            if (osd)
+                osd->ShowStatus(posInfo, false, desc, 1);
+
             ReturnOSDLock(ctx, osd);
         }
         SetUpdateOSDPosition(false);
@@ -10538,7 +10552,9 @@ void TV::SetAutoCommercialSkip(const PlayerContext *ctx,
         if (ctx->CalcNVPSliderPosition(posInfo))
         {
             OSD *osd = GetOSDLock(ctx);
-            osd->ShowStatus(posInfo, false, desc, 1);
+            if (osd)
+                osd->ShowStatus(posInfo, false, desc, 1);
+
             ReturnOSDLock(ctx, osd);
         }
         SetUpdateOSDPosition(false);
@@ -10560,7 +10576,9 @@ void TV::SetManualZoom(const PlayerContext *ctx, bool zoomON, QString desc)
         if (ctx->CalcNVPSliderPosition(posInfo))
         {
             OSD *osd = GetOSDLock(ctx);
-            osd->ShowStatus(posInfo, false, desc, 1);
+            if (osd)
+                osd->ShowStatus(posInfo, false, desc, 1);
+
             ReturnOSDLock(ctx, osd);
         }
         SetUpdateOSDPosition(false);
diff --git a/mythtv/libs/libmythtv/util-vdpau.cpp b/mythtv/libs/libmythtv/util-vdpau.cpp
index 62b5c15..d0dc246 100644
--- a/mythtv/libs/libmythtv/util-vdpau.cpp
+++ b/mythtv/libs/libmythtv/util-vdpau.cpp
@@ -1188,17 +1188,20 @@ void VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,
     VdpVideoMixerPictureStructure field =
         VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
 
-    if (scan == kScan_Interlaced && deinterlacing)
+    if (frame)
     {
-        field = frame->top_field_first ?
-                VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD :
-                VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
-    }
-    else if (scan == kScan_Intr2ndField && deinterlacing)
-    {
-        field = frame->top_field_first ?
-                VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD :
-                VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
+        if (scan == kScan_Interlaced && deinterlacing)
+        {
+            field = frame->top_field_first ?
+                    VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD :
+                    VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
+        }
+        else if (scan == kScan_Intr2ndField && deinterlacing)
+        {
+            field = frame->top_field_first ?
+                    VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD :
+                    VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
+        }
     }
     else if (!frame && deinterlacing)
     {
diff --git a/mythtv/libs/libmythtv/videoout_vdpau.cpp b/mythtv/libs/libmythtv/videoout_vdpau.cpp
index 2f69f33..b3b815c 100644
--- a/mythtv/libs/libmythtv/videoout_vdpau.cpp
+++ b/mythtv/libs/libmythtv/videoout_vdpau.cpp
@@ -267,6 +267,12 @@ void VideoOutputVDPAU::ProcessFrame(VideoFrame *frame, OSD *osd,
 
 void VideoOutputVDPAU::PrepareFrame(VideoFrame *frame, FrameScanType scan)
 {
+    if (!m_ctx)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "No context");
+        return;
+    }
+
     if (m_ctx->IsErrored())
         errorState = m_ctx->GetError();
 
@@ -279,9 +285,6 @@ void VideoOutputVDPAU::PrepareFrame(VideoFrame *frame, FrameScanType scan)
     if (frame)
         framesPlayed = frame->frameNumber + 1;
 
-    if (!m_ctx)
-        return;
-
     m_ctx->PrepareVideo(
         frame, windows[0].GetVideoRect(), 
         vsz_enabled ? vsz_desired_display_rect :
@@ -303,6 +306,12 @@ void VideoOutputVDPAU::DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
     (void)w;
     (void)h;
 
+    if (!m_ctx)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "No context");
+        return;
+    }
+
     if (m_ctx->IsErrored())
         errorState = m_ctx->GetError();
 
@@ -312,8 +321,7 @@ void VideoOutputVDPAU::DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
         return;
     }
 
-    if (m_ctx)
-        m_ctx->Decode(frame);
+    m_ctx->Decode(frame);
 }
 
 void VideoOutputVDPAU::Show(FrameScanType scan)
diff --git a/mythtv/libs/libmythtv/videooutbase.cpp b/mythtv/libs/libmythtv/videooutbase.cpp
index 6183412..b53f875 100644
--- a/mythtv/libs/libmythtv/videooutbase.cpp
+++ b/mythtv/libs/libmythtv/videooutbase.cpp
@@ -1120,7 +1120,7 @@ void VideoOutput::ResizeVideo(VideoFrame *frame)
     // if resize == existing frame, no need to carry on
     abort |= !resize.left() && !resize.top() && (resize.size() == frameDim);
 
-    if (abort)
+    if (abort || !vsz_tmp_buf)
     {
         vsz_enabled = false;
         ShutdownVideoResize();
@@ -1130,7 +1130,7 @@ void VideoOutput::ResizeVideo(VideoFrame *frame)
 
     DoVideoResize(frameDim, resize.size());
 
-    if (vsz_tmp_buf && vsz_scale_context)
+    if (vsz_scale_context)
     {
         AVPicture img_in, img_out;
 
