@@ -109,7 +109,6 @@ def __init__(
109109 self .flags |= MAGIC_NO_CHECK_SIMH
110110
111111 self .cookie = magic_open (self .flags )
112- self .lock = threading .Lock ()
113112
114113 magic_load (self .cookie , magic_file )
115114
@@ -138,34 +137,31 @@ def from_buffer(self, buf):
138137 """
139138 Identify the contents of `buf`
140139 """
141- with self .lock :
142- try :
143- # if we're on python3, convert buf to bytes
144- # otherwise this string is passed as wchar*
145- # which is not what libmagic expects
146- # NEXTBREAK: only take bytes
147- if type (buf ) == str and str != bytes :
148- buf = buf .encode ("utf-8" , errors = "replace" )
149- return maybe_decode (magic_buffer (self .cookie , buf ))
150- except MagicException as e :
151- return self ._handle509Bug (e )
140+ try :
141+ # if we're on python3, convert buf to bytes
142+ # otherwise this string is passed as wchar*
143+ # which is not what libmagic expects
144+ # NEXTBREAK: only take bytes
145+ if type (buf ) == str and str != bytes :
146+ buf = buf .encode ("utf-8" , errors = "replace" )
147+ return maybe_decode (magic_buffer (self .cookie , buf ))
148+ except MagicException as e :
149+ return self ._handle509Bug (e )
152150
153151 def from_file (self , filename ):
154152 # raise FileNotFoundException or IOError if the file does not exist
155153 os .stat (filename , follow_symlinks = self .flags & MAGIC_SYMLINK )
156154
157- with self .lock :
158- try :
159- return maybe_decode (magic_file (self .cookie , filename ))
160- except MagicException as e :
161- return self ._handle509Bug (e )
155+ try :
156+ return maybe_decode (magic_file (self .cookie , filename ))
157+ except MagicException as e :
158+ return self ._handle509Bug (e )
162159
163160 def from_descriptor (self , fd ):
164- with self .lock :
165- try :
166- return maybe_decode (magic_descriptor (self .cookie , fd ))
167- except MagicException as e :
168- return self ._handle509Bug (e )
161+ try :
162+ return maybe_decode (magic_descriptor (self .cookie , fd ))
163+ except MagicException as e :
164+ return self ._handle509Bug (e )
169165
170166 def _handle509Bug (self , e ):
171167 # libmagic 5.09 has a bug where it might fail to identify the
@@ -317,6 +313,9 @@ def coerce_filename(filename):
317313 return filename
318314
319315
316+ # libmagic is not thread-safe: guard for concurrent calls on a global scope
317+ LOCK = threading .Lock ()
318+
320319magic_open = libmagic .magic_open
321320magic_open .restype = magic_t
322321magic_open .argtypes = [c_int ]
@@ -340,7 +339,8 @@ def coerce_filename(filename):
340339
341340
342341def magic_file (cookie , filename ):
343- return _magic_file (cookie , coerce_filename (filename ))
342+ with LOCK :
343+ return _magic_file (cookie , coerce_filename (filename ))
344344
345345
346346_magic_buffer = libmagic .magic_buffer
@@ -350,7 +350,8 @@ def magic_file(cookie, filename):
350350
351351
352352def magic_buffer (cookie , buf ):
353- return _magic_buffer (cookie , buf , len (buf ))
353+ with LOCK :
354+ return _magic_buffer (cookie , buf , len (buf ))
354355
355356
356357magic_descriptor = libmagic .magic_descriptor
@@ -365,7 +366,8 @@ def magic_buffer(cookie, buf):
365366
366367
367368def magic_descriptor (cookie , fd ):
368- return _magic_descriptor (cookie , fd )
369+ with LOCK :
370+ return _magic_descriptor (cookie , fd )
369371
370372
371373_magic_load = libmagic .magic_load
@@ -375,7 +377,8 @@ def magic_descriptor(cookie, fd):
375377
376378
377379def magic_load (cookie , filename ):
378- return _magic_load (cookie , coerce_filename (filename ))
380+ with LOCK :
381+ return _magic_load (cookie , coerce_filename (filename ))
379382
380383
381384magic_setflags = libmagic .magic_setflags
@@ -408,15 +411,16 @@ def magic_setparam(cookie, param, val):
408411 if not _has_param :
409412 raise NotImplementedError ("magic_setparam not implemented" )
410413 v = c_size_t (val )
411- return _magic_setparam (cookie , param , byref (v ))
414+ with LOCK :
415+ return _magic_setparam (cookie , param , byref (v ))
412416
413417
414418def magic_getparam (cookie , param ):
415419 if not _has_param :
416420 raise NotImplementedError ("magic_getparam not implemented" )
417421 val = c_size_t ()
418- _magic_getparam ( cookie , param , byref ( val ))
419- return val .value
422+ with LOCK :
423+ return _magic_getparam ( cookie , param , byref ( val )) .value
420424
421425
422426_has_version = False
@@ -427,10 +431,11 @@ def magic_getparam(cookie, param):
427431 magic_version .argtypes = []
428432
429433
430- def version ():
434+ def version (lock = None ):
431435 if not _has_version :
432436 raise NotImplementedError ("magic_version not implemented" )
433- return magic_version ()
437+ with LOCK :
438+ return magic_version ()
434439
435440
436441MAGIC_NONE = 0x000000 # No flags
0 commit comments