Ticket #7149: libs_libmythtv-pointer-checks

File libs_libmythtv-pointer-checks, 14.9 KB (added by Erik Hovland <erik@…>, 11 years ago)

Fix pointer checks in libmythtv

Line 
1Pointer validity checking defectsg
2
3From: Erik Hovland <erik@hovland.org>
4
51. player_ctx is dereferenced many times before it is checked in this
6   conditional. If player_ctx is going to be checked in this function
7   it likely should be the first thing doneg
8
92. New set of ringBuffer checking. Plus an ic check
10
113. mon needs to be checked before dereferencingg
12
134. rotor checking
14
155. FiltChain needs checking
16
176. return if _rtsp_client is invalid, that way it isn't
18   dereferenced a few lines laterg
19
207. Check m_priv
21
228. Check mctx before hitting its locksg
23
249. Calling SetErrored on ctx will dereference ctxg
25
2610. Assign pointer from GetSet() so that we don't call GetSet twice
27
2811. Check mctx againg
29
3012. Don't need to check mctx now since we did it earlier
31
3213. Check actx
33
3414. Check validity of osd
35
3615. Another mctx check
37
3816. And another time where we can remove a check because we now do it
39    earlier
40
4117. osd checks
42
4318. Check frame
44
4519. Check m_ctx
46
4720. vsz_tmp_buf will be dereferenced by ShutdownVideoResize so move the
48    check up
49
5021. Remove later check
51---
52
53 mythtv/libs/libmythtv/NuppelVideoPlayer.cpp        |    2 -
54 mythtv/libs/libmythtv/avformatdecoder.cpp          |    6 +-
55 .../libs/libmythtv/channelscan/channelscanner.cpp  |    2 -
56 mythtv/libs/libmythtv/dvbsignalmonitor.cpp         |    2 +
57 mythtv/libs/libmythtv/filtermanager.cpp            |    2 -
58 mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp      |    1
59 mythtv/libs/libmythtv/linuxfirewiredevice.cpp      |    3 +
60 mythtv/libs/libmythtv/tv_play.cpp                  |   54 +++++++++++++-------
61 mythtv/libs/libmythtv/util-vdpau.cpp               |   23 +++++----
62 mythtv/libs/libmythtv/videoout_vdpau.cpp           |   18 +++++--
63 mythtv/libs/libmythtv/videooutbase.cpp             |    4 +
64 11 files changed, 76 insertions(+), 41 deletions(-)
65
66
67diff --git a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp b/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
68index 9f31189..a136702 100644
69--- a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
70+++ b/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
71@@ -4742,7 +4742,7 @@ bool NuppelVideoPlayer::IsNearEnd(long long margin) const
72 
73     framesRead = GetDecoder()->GetFramesRead();
74 
75-    if (player_ctx && !player_ctx->IsPIP() &&
76+    if (!player_ctx->IsPIP() &&
77         player_ctx->GetState() == kState_WatchingPreRecorded)
78     {
79         framesLeft = margin;
80diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
81index 06350da..56046de 100644
82--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
83+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
84@@ -1175,7 +1175,7 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
85 
86     float aspect_ratio = 0.0;
87 
88-    if (ringBuffer->isDVD())
89+    if (ringBuffer && ringBuffer->isDVD())
90         directrendering = false;
91 
92     if (selectedStream)
93@@ -1569,7 +1569,7 @@ int AvFormatDecoder::ScanStreams(bool novideo)
94     map<int,uint> lang_sub_cnt;
95     map<int,uint> lang_aud_cnt;
96 
97-    if (ringBuffer->isDVD() &&
98+    if (ringBuffer && ringBuffer->isDVD() &&
99         ringBuffer->DVD()->AudioStreamsChanged())
100     {
101         ringBuffer->DVD()->AudioStreamsChanged(false);
102@@ -4212,7 +4212,7 @@ bool AvFormatDecoder::SetupAudioStream(void)
103     AudioInfo old_out = audioOut;
104     bool using_passthru = false;
105 
106-    if ((currentTrack[kTrackTypeAudio] >= 0) &&
107+    if ((currentTrack[kTrackTypeAudio] >= 0) && ic &&
108         (selectedTrack[kTrackTypeAudio].av_stream_index <=
109          (int) ic->nb_streams) &&
110         (curstream = ic->streams[selectedTrack[kTrackTypeAudio]
111diff --git a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
112index 0ecb376..9b05470 100644
113--- a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
114+++ b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp
115@@ -416,7 +416,7 @@ void ChannelScanner::PreScanCommon(
116 
117 #ifdef USING_DVB
118     dvbm = sigmonScanner->GetDVBSignalMonitor();
119-    if (dvbm)
120+    if (dvbm && mon)
121         using_rotor = mon->HasFlags(SignalMonitor::kDVBSigMon_WaitForPos);
122 #endif // USING_DVB
123 
124diff --git a/mythtv/libs/libmythtv/dvbsignalmonitor.cpp b/mythtv/libs/libmythtv/dvbsignalmonitor.cpp
125index c2742b7..d699c92 100644
126--- a/mythtv/libs/libmythtv/dvbsignalmonitor.cpp
127+++ b/mythtv/libs/libmythtv/dvbsignalmonitor.cpp
128@@ -129,6 +129,8 @@ void DVBSignalMonitor::GetRotorStatus(bool &was_moving, bool &is_moving)
129         return;
130 
131     const DiSEqCDevRotor *rotor = dvbchannel->GetRotor();
132+    if (!rotor)
133+        return;
134 
135     QMutexLocker locker(&statusLock);
136     was_moving = rotorPosition.GetValue() < 100;
137diff --git a/mythtv/libs/libmythtv/filtermanager.cpp b/mythtv/libs/libmythtv/filtermanager.cpp
138index b4e5dae..db3b670 100644
139--- a/mythtv/libs/libmythtv/filtermanager.cpp
140+++ b/mythtv/libs/libmythtv/filtermanager.cpp
141@@ -401,7 +401,7 @@ FilterChain *FilterManager::LoadFilters(QString Filters,
142             break;
143         }
144 
145-        if (NewFilt->filter)
146+        if (NewFilt->filter && FiltChain)
147         {
148             FiltChain->Append(NewFilt);
149         }
150diff --git a/mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp b/mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp
151index f8ed4b1..f34d05e 100644
152--- a/mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp
153+++ b/mythtv/libs/libmythtv/iptv/iptvfeederrtsp.cpp
154@@ -107,6 +107,7 @@ bool IPTVFeederRTSP::Open(const QString &url)
155                 QString("Failed to create RTSP client: %1")
156                 .arg(_live_env->getResultMsg()));
157         FreeEnv();
158+        return false;
159     }
160 
161     // Setup URL for the current session
162diff --git a/mythtv/libs/libmythtv/linuxfirewiredevice.cpp b/mythtv/libs/libmythtv/linuxfirewiredevice.cpp
163index 05ebc93..7da7395 100644
164--- a/mythtv/libs/libmythtv/linuxfirewiredevice.cpp
165+++ b/mythtv/libs/libmythtv/linuxfirewiredevice.cpp
166@@ -984,6 +984,9 @@ LinuxAVCInfo *LinuxFirewireDevice::GetInfoPtr(void)
167 
168 const LinuxAVCInfo *LinuxFirewireDevice::GetInfoPtr(void) const
169 {
170+    if (!m_priv)
171+        return NULL;
172+
173     avcinfo_list_t::iterator it = m_priv->devices.find(m_guid);
174     return (it == m_priv->devices.end()) ? NULL : *it;
175 }
176diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp
177index bb89a83..444aaa7 100644
178--- a/mythtv/libs/libmythtv/tv_play.cpp
179+++ b/mythtv/libs/libmythtv/tv_play.cpp
180@@ -348,10 +348,14 @@ bool TV::StartTV(ProgramInfo *tvrec, bool startInGuide,
181         const PlayerContext *mctx =
182             tv->GetPlayerReadLock(0, __FILE__, __LINE__);
183         quitAll = tv->wantsToQuit || (mctx && mctx->errored);
184-        mctx->LockDeleteNVP(__FILE__, __LINE__);
185-        if (mctx->nvp && mctx->nvp->IsErrored())
186-            nvpError = mctx->nvp->GetError();
187-        mctx->UnlockDeleteNVP(__FILE__, __LINE__);
188+        if (mctx)
189+        {
190+            mctx->LockDeleteNVP(__FILE__, __LINE__);
191+            if (mctx->nvp && mctx->nvp->IsErrored())
192+                nvpError = mctx->nvp->GetError();
193+
194+            mctx->UnlockDeleteNVP(__FILE__, __LINE__);
195+        }
196         tv->ReturnPlayerLock(mctx);
197     }
198 
199@@ -2334,7 +2338,6 @@ void TV::timerEvent(QTimerEvent *te)
200         if (!ok || !pbinfo)
201         {
202             VERBOSE(VB_IMPORTANT, LOC_ERR + "lost contact with backend");
203-            SetErrored(ctx);
204         }
205 
206         ReturnPlayerLock(mctx);
207@@ -2690,8 +2693,9 @@ void TV::timerEvent(QTimerEvent *te)
208     {
209         PlayerContext *actx = GetPlayerReadLock(-1, __FILE__, __LINE__);
210         OSD *osd = GetOSDLock(actx);
211-        if (osd && osd->GetSet("status") &&
212-            osd->GetSet("status")->Displaying() &&
213+        OSDSet *osdset = NULL;
214+        if (osd && (osdset = osd->GetSet("status")) &&
215+            osdset->Displaying() &&
216             (StateIsLiveTV(actx->GetState()) ||
217              StateIsPlaying(actx->GetState())))
218         {
219@@ -2720,6 +2724,8 @@ void TV::timerEvent(QTimerEvent *te)
220     {
221         bool error = false;
222         PlayerContext *mctx = GetPlayerReadLock(0, __FILE__, __LINE__);
223+        if (!mctx)
224+            return;
225 
226         if (mctx->IsNVPErrored())
227         {
228@@ -2747,7 +2753,7 @@ void TV::timerEvent(QTimerEvent *te)
229             error = true;
230         }
231 
232-        for (uint i = 0; mctx && (i < player.size()); i++)
233+        for (uint i = 0; i < player.size(); i++)
234         {
235             PlayerContext *ctx = GetPlayer(mctx, i);
236             if (error || ctx->IsErrored())
237@@ -3141,7 +3147,7 @@ void TV::HandleSpeedChangeTimerEvent(void)
238         update_msg |= ctx->HandleNVPSpeedChangeEOF() && (ctx == actx);
239     }
240 
241-    if (update_msg)
242+    if (actx && update_msg)
243     {
244         UpdateOSDSeekMessage(actx, actx->GetPlayMessage(),
245                              osd_general_timeout);
246@@ -7215,16 +7221,19 @@ void TV::UpdateOSDSignal(const PlayerContext *ctx, const QStringList &strlist)
247     else if (!msg.isEmpty())
248         sigDesc = msg;
249 
250+    infoMap["description"] = sigDesc;
251     //osd->ClearAllText("signal_info");
252     //osd->SetText("signal_info", infoMap, -1);
253 
254     osd = GetOSDLock(ctx);
255-    osd->ClearAllText("channel_number");
256-    osd->SetText("channel_number", infoMap, osd_prog_info_timeout);
257+    if (osd)
258+    {
259+        osd->ClearAllText("channel_number");
260+        osd->SetText("channel_number", infoMap, osd_prog_info_timeout);
261 
262-    infoMap["description"] = sigDesc;
263-    osd->ClearAllText("program_info");
264-    osd->SetText("program_info", infoMap, osd_prog_info_timeout);
265+        osd->ClearAllText("program_info");
266+        osd->SetText("program_info", infoMap, osd_prog_info_timeout);
267+    }
268     ReturnOSDLock(ctx, osd);
269 
270     ctx->lastSignalMsg.clear();
271@@ -8332,13 +8341,16 @@ void TV::customEvent(QEvent *e)
272                 << " haslater: " << haslater);
273 
274         PlayerContext *mctx = GetPlayerReadLock(0, __FILE__, __LINE__);
275+        if (!mctx)
276+            return;
277+
278         if (mctx->recorder && cardnum == mctx->GetCardID())
279         {
280             AskAllowRecording(mctx, me->ExtraDataList(),
281                               timeuntil, hasrec, haslater);
282         }
283 
284-        for (uint i = 1; mctx && (i < player.size()); i++)
285+        for (uint i = 1; i < player.size(); i++)
286         {
287             PlayerContext *ctx = GetPlayer(mctx, i);
288             if (ctx->recorder && ctx->GetCardID() == cardnum)
289@@ -10512,7 +10524,9 @@ void TV::ToggleAutoExpire(PlayerContext *ctx)
290         if (ctx->CalcNVPSliderPosition(posInfo))
291         {
292             OSD *osd = GetOSDLock(ctx);
293-            osd->ShowStatus(posInfo, false, desc, 1);
294+            if (osd)
295+                osd->ShowStatus(posInfo, false, desc, 1);
296+
297             ReturnOSDLock(ctx, osd);
298         }
299         SetUpdateOSDPosition(false);
300@@ -10538,7 +10552,9 @@ void TV::SetAutoCommercialSkip(const PlayerContext *ctx,
301         if (ctx->CalcNVPSliderPosition(posInfo))
302         {
303             OSD *osd = GetOSDLock(ctx);
304-            osd->ShowStatus(posInfo, false, desc, 1);
305+            if (osd)
306+                osd->ShowStatus(posInfo, false, desc, 1);
307+
308             ReturnOSDLock(ctx, osd);
309         }
310         SetUpdateOSDPosition(false);
311@@ -10560,7 +10576,9 @@ void TV::SetManualZoom(const PlayerContext *ctx, bool zoomON, QString desc)
312         if (ctx->CalcNVPSliderPosition(posInfo))
313         {
314             OSD *osd = GetOSDLock(ctx);
315-            osd->ShowStatus(posInfo, false, desc, 1);
316+            if (osd)
317+                osd->ShowStatus(posInfo, false, desc, 1);
318+
319             ReturnOSDLock(ctx, osd);
320         }
321         SetUpdateOSDPosition(false);
322diff --git a/mythtv/libs/libmythtv/util-vdpau.cpp b/mythtv/libs/libmythtv/util-vdpau.cpp
323index 62b5c15..d0dc246 100644
324--- a/mythtv/libs/libmythtv/util-vdpau.cpp
325+++ b/mythtv/libs/libmythtv/util-vdpau.cpp
326@@ -1188,17 +1188,20 @@ void VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,
327     VdpVideoMixerPictureStructure field =
328         VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
329 
330-    if (scan == kScan_Interlaced && deinterlacing)
331+    if (frame)
332     {
333-        field = frame->top_field_first ?
334-                VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD :
335-                VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
336-    }
337-    else if (scan == kScan_Intr2ndField && deinterlacing)
338-    {
339-        field = frame->top_field_first ?
340-                VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD :
341-                VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
342+        if (scan == kScan_Interlaced && deinterlacing)
343+        {
344+            field = frame->top_field_first ?
345+                    VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD :
346+                    VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
347+        }
348+        else if (scan == kScan_Intr2ndField && deinterlacing)
349+        {
350+            field = frame->top_field_first ?
351+                    VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD :
352+                    VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
353+        }
354     }
355     else if (!frame && deinterlacing)
356     {
357diff --git a/mythtv/libs/libmythtv/videoout_vdpau.cpp b/mythtv/libs/libmythtv/videoout_vdpau.cpp
358index 2f69f33..b3b815c 100644
359--- a/mythtv/libs/libmythtv/videoout_vdpau.cpp
360+++ b/mythtv/libs/libmythtv/videoout_vdpau.cpp
361@@ -267,6 +267,12 @@ void VideoOutputVDPAU::ProcessFrame(VideoFrame *frame, OSD *osd,
362 
363 void VideoOutputVDPAU::PrepareFrame(VideoFrame *frame, FrameScanType scan)
364 {
365+    if (!m_ctx)
366+    {
367+        VERBOSE(VB_IMPORTANT, LOC_ERR + "No context");
368+        return;
369+    }
370+
371     if (m_ctx->IsErrored())
372         errorState = m_ctx->GetError();
373 
374@@ -279,9 +285,6 @@ void VideoOutputVDPAU::PrepareFrame(VideoFrame *frame, FrameScanType scan)
375     if (frame)
376         framesPlayed = frame->frameNumber + 1;
377 
378-    if (!m_ctx)
379-        return;
380-
381     m_ctx->PrepareVideo(
382         frame, windows[0].GetVideoRect(),
383         vsz_enabled ? vsz_desired_display_rect :
384@@ -303,6 +306,12 @@ void VideoOutputVDPAU::DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
385     (void)w;
386     (void)h;
387 
388+    if (!m_ctx)
389+    {
390+        VERBOSE(VB_IMPORTANT, LOC_ERR + "No context");
391+        return;
392+    }
393+
394     if (m_ctx->IsErrored())
395         errorState = m_ctx->GetError();
396 
397@@ -312,8 +321,7 @@ void VideoOutputVDPAU::DrawSlice(VideoFrame *frame, int x, int y, int w, int h)
398         return;
399     }
400 
401-    if (m_ctx)
402-        m_ctx->Decode(frame);
403+    m_ctx->Decode(frame);
404 }
405 
406 void VideoOutputVDPAU::Show(FrameScanType scan)
407diff --git a/mythtv/libs/libmythtv/videooutbase.cpp b/mythtv/libs/libmythtv/videooutbase.cpp
408index 6183412..b53f875 100644
409--- a/mythtv/libs/libmythtv/videooutbase.cpp
410+++ b/mythtv/libs/libmythtv/videooutbase.cpp
411@@ -1120,7 +1120,7 @@ void VideoOutput::ResizeVideo(VideoFrame *frame)
412     // if resize == existing frame, no need to carry on
413     abort |= !resize.left() && !resize.top() && (resize.size() == frameDim);
414 
415-    if (abort)
416+    if (abort || !vsz_tmp_buf)
417     {
418         vsz_enabled = false;
419         ShutdownVideoResize();
420@@ -1130,7 +1130,7 @@ void VideoOutput::ResizeVideo(VideoFrame *frame)
421 
422     DoVideoResize(frameDim, resize.size());
423 
424-    if (vsz_tmp_buf && vsz_scale_context)
425+    if (vsz_scale_context)
426     {
427         AVPicture img_in, img_out;
428