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

Code before:
            filename = '/' + filename
        return filename

    @staticmethod
    def _decrypt_url_params(audio_info):
        params = VideaIE.rc4(base64.b64decode(audio_info['ep']),
                             'xkt3a41psizxrh9l').split('-')
        sign, token, timestamp = params[1], params[2], params[3]
        return sign, token, timestamp

    def _real_extract(self, url):
        scheme = 'https' if url.startswith('https') else 'http'

        audio_id = self._match_id(url)
        audio_info_file = f'{scheme}://m.ximalaya.com/tracks/{audio_id}.json'
        audio_info = self._download_json(
            audio_info_file, audio_id,
            f'Downloading info json {audio_info_file}', 'Unable to download info file')

        # NOTE(xcsong): VIP-restricted audio
        if audio_info.get('is_paid'):
            ts = int(time.time())
            audio_info_file = f'{scheme}://mpay.ximalaya.com/mobile/track/pay/{audio_id}/{ts}?device=pc&isBackend=true&_={ts}'
            audio_info = self._download_json(
                audio_info_file, audio_id,
                f'Downloading VIP info json {audio_info_file}', 'Unable to download VIP info file')
            filename = self._decrypt_filename(audio_info)
            sign, token, timestamp = self._decrypt_url_params(audio_info)
            buy_key = audio_info.get('buyKey')
            duration = audio_info.get('duration')
            domain = audio_info.get('domain')
            api_version = audio_info.get('apiVersion')
            args = f'?sign={sign}&buy_key={buy_key}&token={token}&timestamp={timestamp}&duration={duration}'
            audio_info['play_path_64'] = f'{domain}/download/{api_version}{filename}{args}'
            if '_preview_' in audio_info['play_path_64']:
                self.report_warning('Please use correct cookies to download VIP audios!')

        formats = [{
            'format_id': f'{bps}k',
            'url': audio_info[k],
            'abr': bps,
            'vcodec': 'none',
        } for bps, k in ((24, 'play_path_32'), (64, 'play_path_64')) if audio_info.get(k)]

        thumbnails = []
        for k in audio_info:
            # cover pics kyes like: cover_url', 'cover_url_142'
            if k.startswith('cover_url'):
                thumbnail = {'name': k, 'url': audio_info[k]}
                if k == 'cover_url_142':
                    thumbnail['width'] = 180

Review comment (security):
Same thing here:
```suggestion
            audio_info = self._download_json(
                f'{scheme}://mpay.ximalaya.com/mobile/track/pay/{audio_id}/{ts}',
                audio_id, 'Downloading VIP info json', 'Unable to download VIP info file',
                query={'device': 'pc', 'isBackend': 'true', '_': ts})
```
Question: Do we really want to overwrite `audio_info`? This will overwrite all data from the original call. Should we extract both separately, or are all formats/metadata of the free API also included in the paid api? Should we still continue with extraction using the free api data if the users is not authenticated? i.e. are are sometimes only the higher quality formats locked behind a paid account?

Code after:
            cgstr += key[r]
            key = key.replace(key[r], '')
        parts = file_id.split('*')
        filename = ''.join(cgstr[int(part)] for part in parts if part.isdecimal())
        if not filename.startswith('/'):
            filename = '/' + filename
        return filename

    @staticmethod
    def _decrypt_url_params(encrypted_params):
        params = VideaIE.rc4(
            base64.b64decode(encrypted_params), 'xkt3a41psizxrh9l').split('-')
        # sign, token, timestamp
        return params[1], params[2], params[3]

    def _real_extract(self, url):
        scheme = 'https' if url.startswith('https') else 'http'

        audio_id = self._match_id(url)
        audio_info = self._download_json(
            f'{scheme}://m.ximalaya.com/tracks/{audio_id}.json', audio_id,
            'Downloading info json', 'Unable to download info file')

        formats = []
        # NOTE: VIP-restricted audio
        if audio_info.get('is_paid'):
            ts = int(time.time())
            vip_info = self._download_json(
                f'{scheme}://mpay.ximalaya.com/mobile/track/pay/{audio_id}/{ts}',
                audio_id, 'Downloading VIP info json', 'Unable to download VIP info file',
                query={'device': 'pc', 'isBackend': 'true', '_': ts})
            filename = self._decrypt_filename(vip_info['fileId'], vip_info['seed'])
            sign, token, timestamp = self._decrypt_url_params(vip_info['ep'])
            vip_url = update_url_query(
                f'{vip_info["domain"]}/download/{vip_info["apiVersion"]}{filename}', {
                    'sign': sign,
                    'token': token,
                    'timestamp': timestamp,
                    'buy_key': vip_info['buyKey'],
                    'duration': vip_info['duration'],
                })
            fmt = {
                'format_id': 'vip',
                'url': vip_url,
                'vcodec': 'none',
            }
            if '_preview_' in vip_url:
                self.report_warning(
                    f'This tracks requires a VIP account. Using a sample instead. {self._login_hint()}')
                fmt.update({
                    'format_note': 'Sample',