Compare commits

...

3 Commits

Author SHA1 Message Date
doe1080
cb309b3293
[utils] HTTPHeaderDict: Fix __ior__ (#16930)
Authored by: doe1080
2026-06-11 16:43:24 +02:00
bashonly
e47691215f
Fix allow-unsafe-ext compat option (#16920)
Fix bug in e578e265f7c6ca94a74b30e0d8d6196a4d19fb6a

Closes #16919
Authored by: bashonly
2026-06-10 23:00:05 +00:00
bashonly
a541df1ea5
[ie/bandcamp:weekly] Fix extractor (#16925)
Closes #16924
Authored by: bashonly
2026-06-10 22:34:16 +00:00
5 changed files with 28 additions and 7 deletions

View File

@ -327,6 +327,12 @@ class TestUtil(unittest.TestCase):
with self.assertRaises(_UnsafeExtensionError):
prepend_extension('abc.unexpected_ext', ext, 'ext')
# Test allow-unsafe-ext compat option
_UnsafeExtensionError._enabled = False
self.assertEqual(prepend_extension('abc.ext', 'un/safe'), 'abc.un/safe.ext')
# Re-enable sanitization for other tests
_UnsafeExtensionError._enabled = True
def test_replace_extension(self):
self.assertEqual(replace_extension('abc.ext', 'temp'), 'abc.temp')
self.assertEqual(replace_extension('abc.ext', 'temp', 'ext'), 'abc.temp')
@ -345,6 +351,12 @@ class TestUtil(unittest.TestCase):
with self.assertRaises(_UnsafeExtensionError):
replace_extension('abc.unexpected_ext', ext, 'ext')
# Test allow-unsafe-ext compat option
_UnsafeExtensionError._enabled = False
self.assertEqual(replace_extension('abc.ext', 'bin'), 'abc.bin')
# Re-enable sanitization for other tests
_UnsafeExtensionError._enabled = True
def test_subtitles_filename(self):
self.assertEqual(subtitles_filename('abc.ext', 'en', 'vtt'), 'abc.en.vtt')
self.assertEqual(subtitles_filename('abc.ext', 'en', 'vtt', 'ext'), 'abc.en.vtt')
@ -2160,6 +2172,10 @@ Line 1
headers6 = HTTPHeaderDict(a=1, b=2)
self.assertEqual(pickle.loads(pickle.dumps(headers6)), headers6)
headers7 = HTTPHeaderDict()
headers7 |= {'X-dlp': 'data'}
self.assertEqual(headers7.sensitive(), {'X-dlp': 'data'})
def test_extract_basic_auth(self):
assert extract_basic_auth('http://:foo.bar') == ('http://:foo.bar', None)
assert extract_basic_auth('http://foo.bar') == ('http://foo.bar', None)

View File

@ -619,7 +619,7 @@ def validate_options(opts):
warnings.append(
'Using allow-unsafe-ext opens you up to potential attacks. '
'Use with great care!')
_UnsafeExtensionError.sanitize_extension = lambda x, prepend=False: x
_UnsafeExtensionError._enabled = False
return warnings, deprecation_warnings

View File

@ -420,10 +420,10 @@ class BandcampWeeklyIE(BandcampIE): # XXX: Do not subclass from concrete IE
'info_dict': {
'id': '224',
'ext': 'mp3',
'title': 'Bandcamp Weekly, 2017-04-04',
'title': 'Magic Moments, 2017-04-04',
'description': 'md5:5d48150916e8e02d030623a48512c874',
'thumbnail': 'https://f4.bcbits.com/img/9982549_0.jpg',
'series': 'Bandcamp Weekly',
'series': 'Magic Moments',
'episode_id': '224',
'release_timestamp': 1491264000,
'release_date': '20170404',
@ -440,10 +440,10 @@ class BandcampWeeklyIE(BandcampIE): # XXX: Do not subclass from concrete IE
def _real_extract(self, url):
show_id = self._match_id(url)
show_data = self._download_json(
'https://bandcamp.com/api/bcradio_api/1/get_show',
'https://bandcamp.com/api/player/2/player_data_web',
show_id, 'Downloading radio show JSON',
data=json.dumps({'id': show_id}).encode(),
headers={'Content-Type': 'application/json'})
data=json.dumps({'item_id': int(show_id), 'item_type': 'radio'}).encode(),
headers={'Content-Type': 'application/json'})['tracklist']
audio_data = show_data['compiledTrack']
stream_url = audio_data['streamUrl']

View File

@ -5218,12 +5218,17 @@ class _UnsafeExtensionError(Exception):
'sbv',
])
_enabled = True
def __init__(self, extension, /):
super().__init__(f'unsafe file extension: {extension!r}')
self.extension = extension
@classmethod
def sanitize_extension(cls, extension, /, *, prepend=False, _allowed_exts=()):
if not cls._enabled:
return extension
if extension is None:
return None

View File

@ -64,7 +64,7 @@ class HTTPHeaderDict(dict):
other = other.sensitive()
if isinstance(other, dict):
self.update(other)
return
return self
return NotImplemented
def __or__(self, other, /) -> typing.Self: