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

Code before:
                            raise ExtractorError('You denied access to an account', expected=True, video_id=self._OAUTH_DISPLAY_ID)
                        elif error == 'slow_down':
                            # RFC8628 § 3.5: add 5 seconds to the poll interval
                            poll_interval += 5
                            time.sleep(poll_interval)
                            continue
                        else:
                            raise ExtractorError(
                                f'Authorization server returned an error when fetching access token: {error}',
                                video_id=self._OAUTH_DISPLAY_ID)
                    raise

                return token_response

    def _update_oauth(self):
        token = YoutubeBaseInfoExtractor._OAUTH_ACCESS_TOKEN_CACHE.get(self._OAUTH_PROFILE)
        if token is None or token['expiry'] > time.time():
            return

        self._set_oauth_info(self._refresh_token(token['refresh_token']))

    @property
    def _youtube_login_hint(self):
        return ('Use  --username=oauth[+PROFILE] --password=""  to log in using oauth, '
                f'or else u{self._login_hint(method="cookies")[1:]}'
                f' or  https://github.com/yt-dlp/yt-dlp/wiki/Extractors#logging-in-with-oauth  on how to use oauth')

    def _check_login_required(self):
        if self._LOGIN_REQUIRED and not self.is_authenticated:
            self.raise_login_required(
                f'Login details are needed to download this content. {self._youtube_login_hint}', method=None)

    _YT_INITIAL_DATA_RE = r'(?:window\s*\[\s*["\']ytInitialData["\']\s*\]|ytInitialData)\s*='
    _YT_INITIAL_PLAYER_RESPONSE_RE = r'ytInitialPlayerResponse\s*='

    def _get_default_ytcfg(self, client='web'):
        return copy.deepcopy(INNERTUBE_CLIENTS[client])

    def _get_innertube_host(self, client='web'):
        return INNERTUBE_CLIENTS[client]['INNERTUBE_HOST']

    def _ytcfg_get_safe(self, ytcfg, getter, expected_type=None, default_client='web'):
        # try_get but with fallback to default ytcfg client values when present
        _func = lambda y: try_get(y, getter, expected_type)
        return _func(ytcfg) or _func(self._get_default_ytcfg(default_client))

    def _extract_client_name(self, ytcfg, default_client='web'):
        return self._ytcfg_get_safe(
            ytcfg, (lambda x: x['INNERTUBE_CLIENT_NAME'],
                    lambda x: x['INNERTUBE_CONTEXT']['client']['clientName']), str, default_client)


Review comment (security):
```suggestion
        return ('Use  --username=oauth[+PROFILE] --password=""  to log in using oauth, '
                f'or else u{self._login_hint(method="cookies")[1:]}. '
                'See  https://github.com/yt-dlp/yt-dlp/wiki/Extractors#logging-in-with-oauth  for more on how to use oauth. '
                'See  https://github.com/yt-dlp/yt-dlp/wiki/Extractors#exporting-youtube-cookies  for help with cookies')
```

Code after:
                        elif error == 'expired_token':
                            raise ExtractorError(
                                'Authorization timed out', expected=True, video_id=self._OAUTH_DISPLAY_ID)
                        elif error == 'access_denied':
                            raise ExtractorError(
                                'You denied access to an account', expected=True, video_id=self._OAUTH_DISPLAY_ID)
                        elif error == 'slow_down':
                            # RFC8628 § 3.5: add 5 seconds to the poll interval
                            poll_interval += 5
                            time.sleep(poll_interval)
                            continue
                        else:
                            raise ExtractorError(
                                f'Authorization server returned an error when fetching access token: {error}',
                                video_id=self._OAUTH_DISPLAY_ID)
                    raise

                return token_response

    def _update_oauth(self):
        token = YoutubeBaseInfoExtractor._OAUTH_ACCESS_TOKEN_CACHE.get(self._OAUTH_PROFILE)
        if token is None or token['expiry'] > time.time():
            return

        self._set_oauth_info(self._refresh_token(token['refresh_token']))

    @property
    def _youtube_login_hint(self):
        return ('Use  --username=oauth[+PROFILE] --password=""  to log in using oauth, '
                f'or else u{self._login_hint(method="cookies")[1:]}. '
                'See  https://github.com/yt-dlp/yt-dlp/wiki/Extractors#logging-in-with-oauth  for more on how to use oauth. '
                'See  https://github.com/yt-dlp/yt-dlp/wiki/Extractors#exporting-youtube-cookies  for help with cookies')

    def _check_login_required(self):
        if self._LOGIN_REQUIRED and not self.is_authenticated:
            self.raise_login_required(
                f'Login details are needed to download this content. {self._youtube_login_hint}', method=None)

    _YT_INITIAL_DATA_RE = r'(?:window\s*\[\s*["\']ytInitialData["\']\s*\]|ytInitialData)\s*='
    _YT_INITIAL_PLAYER_RESPONSE_RE = r'ytInitialPlayerResponse\s*='

    def _get_default_ytcfg(self, client='web'):
        return copy.deepcopy(INNERTUBE_CLIENTS[client])

    def _get_innertube_host(self, client='web'):
        return INNERTUBE_CLIENTS[client]['INNERTUBE_HOST']

    def _ytcfg_get_safe(self, ytcfg, getter, expected_type=None, default_client='web'):
        # try_get but with fallback to default ytcfg client values when present
        _func = lambda y: try_get(y, getter, expected_type)
        return _func(ytcfg) or _func(self._get_default_ytcfg(default_client))