Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/globalplayer.py (Python)

Code before:
        'playlist_mincount': 3,
    }]

    def _real_extract(self, url):
        video_id, podcast = self._match_valid_url(url).group('id', 'podcast')
        props = self._get_pageProps(url, video_id)

        if podcast:
            series = props['podcastInfo']
            categories = [i.get('name') for i in series.get('categories')]
        else:
            series = props['catchupInfo']
            categories = None

        return {
            '_type': 'playlist',
            'categories': categories,  # podcasts only
            'entries': [self._extract_audio(ep, series) for ep in series['episodes']],
            **traverse_obj(series, {
                'description': 'description',
                'id': 'id',
                'thumbnail': 'imageUrl',
                'title': 'title',
                'uploader': 'itunesAuthor',  # podcasts only
            }),
        }


class GlobalPlayerAudioEpisodeIE(GlobalPlayerBaseIE):
    _VALID_URL = r'https?://www\.globalplayer\.com/(?:(?P<podcast>podcasts)|catchup/\w+/\w+)/episodes/(?P<id>\w+)/$'
    _TESTS = [{
        # podcast
        'url': 'https://www.globalplayer.com/podcasts/episodes/7DrfNnE/',
        'info_dict': {
            'id': '7DrfNnE',
            'ext': 'mp3',
            'title': 'Filthy Ritual - Trailer',
            'duration': 225,
            'description': 'md5:1f1562fd0f01b4773b590984f94223e0',
            'thumbnail': 'md5:60286e7d12d795bd1bbc9efc6cee643e',
            'upload_date': '20230411',
            'timestamp': 1681254900,
            'series': 'Filthy Ritual',
            'series_id': '42KuaM',

        }
    }, {
        # radio catchup
        'url': 'https://www.globalplayer.com/catchup/lbc/uk/episodes/2zGq26Vcv1fCWhddC4JAwETXWe/',
        'info_dict': {
            'id': '2zGq26Vcv1fCWhddC4JAwETXWe',

Review comment (security):
with traversal we can filter for entries with `id` and `url` keys/truthy values
```suggestion
        return {
            '_type': 'playlist',
            'id': video_id,
            'entries': [self._extract_audio(ep, series) for ep in traverse_obj(
                        series, ('episodes', lambda _, v: v['id'] and v['streamUrl']))],
            'categories': traverse_obj(series, ('categories', ..., 'name')) or None,
            **traverse_obj(series, {
                'description': 'description',
                'thumbnail': 'imageUrl',
                'title': 'title',
                'uploader': 'itunesAuthor',  # podcasts only
            }),
        }
```

Code after:
            'id': video_id,
            'entries': [self._extract_audio(ep, series) for ep in traverse_obj(
                        series, ('episodes', lambda _, v: v['id'] and v['streamUrl']))],
            'categories': traverse_obj(series, ('categories', ..., 'name')) or None,
            **traverse_obj(series, {
                'description': 'description',
                'thumbnail': 'imageUrl',
                'title': 'title',
                'uploader': 'itunesAuthor',  # podcasts only
            }),
        }


class GlobalPlayerAudioEpisodeIE(GlobalPlayerBaseIE):
    _VALID_URL = r'https?://www\.globalplayer\.com/(?:(?P<podcast>podcasts)|catchup/\w+/\w+)/episodes/(?P<id>\w+)/?(?:$|[?#])'
    _TESTS = [{
        # podcast
        'url': 'https://www.globalplayer.com/podcasts/episodes/7DrfNnE/',
        'info_dict': {
            'id': '7DrfNnE',
            'ext': 'mp3',
            'title': 'Filthy Ritual - Trailer',
            'description': 'md5:1f1562fd0f01b4773b590984f94223e0',
            'thumbnail': 'md5:60286e7d12d795bd1bbc9efc6cee643e',
            'duration': 225.0,
            'timestamp': 1681254900,
            'series': 'Filthy Ritual',
            'series_id': '42KuaM',
            'upload_date': '20230411',
            'uploader': 'Global',
        },
    }, {
        # radio catchup
        'url': 'https://www.globalplayer.com/catchup/lbc/uk/episodes/2zGq26Vcv1fCWhddC4JAwETXWe/',
        'info_dict': {
            'id': '2zGq26Vcv1fCWhddC4JAwETXWe',
            'ext': 'm4a',
            'timestamp': 1682056800,
            'series': 'Nick Ferrari',
            'thumbnail': 'md5:4df24d8a226f5b2508efbcc6ae874ebf',
            'upload_date': '20230421',
            'series_id': '46vyD7z',
            'description': 'Nick Ferrari At Breakfast is Leading Britain\'s Conversation.',
            'title': 'Nick Ferrari',
            'duration': 10800.0,
        },
    }]

    def _real_extract(self, url):
        video_id, podcast = self._match_valid_url(url).group('id', 'podcast')
        props = self._get_page_props(url, video_id)