Moving static tagName() into Image class to prevent multithread crashes.
static variables inside of tagName() were not protected against multithread access. It could cause a crash in case of simultaneous initialization of map of tags.
This commit is contained in:
parent
0f72599121
commit
ddb87fe0cf
@ -502,12 +502,18 @@ namespace Exiv2 {
|
||||
Image& operator=(const Image& rhs);
|
||||
//@}
|
||||
|
||||
const char* tagName(uint16_t tag,size_t nMaxLength);
|
||||
|
||||
// DATA
|
||||
int imageType_; //!< Image type
|
||||
uint16_t supportedMetadata_; //!< Bitmap with all supported metadata types
|
||||
bool writeXmpFromPacket_;//!< Determines the source when writing XMP
|
||||
ByteOrder byteOrder_; //!< Byte order
|
||||
|
||||
std::map<int,std::string> tags; //!< Map of tags
|
||||
bool init; //!< Flag marking if map of tags needs to be initialized
|
||||
char buffer[80];
|
||||
|
||||
}; // class Image
|
||||
|
||||
//! Type for function pointer that creates new Image instances
|
||||
|
||||
@ -162,7 +162,10 @@ namespace Exiv2 {
|
||||
#else
|
||||
writeXmpFromPacket_(true),
|
||||
#endif
|
||||
byteOrder_(invalidByteOrder)
|
||||
byteOrder_(invalidByteOrder),
|
||||
tags(),
|
||||
init(true),
|
||||
buffer()
|
||||
{
|
||||
}
|
||||
|
||||
@ -273,40 +276,6 @@ namespace Exiv2 {
|
||||
return Image::byteSwap(v,bSwap);
|
||||
}
|
||||
|
||||
static const char* tagName(uint16_t tag,size_t nMaxLength)
|
||||
{
|
||||
const char* result = NULL;
|
||||
|
||||
// build a static map of tags for fast search
|
||||
static std::map<int,std::string> tags;
|
||||
static bool init = true;
|
||||
static char buffer[80];
|
||||
|
||||
if ( init ) {
|
||||
int idx;
|
||||
const TagInfo* ti ;
|
||||
for (ti = Internal:: mnTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal:: iopTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal:: gpsTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal:: ifdTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal::exifTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal:: mpfTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal::Nikon1MakerNote::tagList(), idx = 0
|
||||
; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
}
|
||||
init = false;
|
||||
|
||||
try {
|
||||
result = tags[tag].c_str();
|
||||
if ( nMaxLength > sizeof(buffer) -2 )
|
||||
nMaxLength = sizeof(buffer) -2;
|
||||
strncpy(buffer,result,nMaxLength);
|
||||
result = buffer;
|
||||
} catch ( ... ) {}
|
||||
|
||||
return result ;
|
||||
}
|
||||
|
||||
static const char* typeName(uint16_t tag)
|
||||
{
|
||||
//! List of TIFF image tags
|
||||
@ -727,6 +696,35 @@ namespace Exiv2 {
|
||||
return ImageFactory::checkMode(imageType_, metadataId);
|
||||
}
|
||||
|
||||
const char* Image::tagName(uint16_t tag,size_t nMaxLength)
|
||||
{
|
||||
const char* result = NULL;
|
||||
|
||||
if ( init ) {
|
||||
int idx;
|
||||
const TagInfo* ti ;
|
||||
for (ti = Internal:: mnTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal:: iopTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal:: gpsTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal:: ifdTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal::exifTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal:: mpfTagList(), idx = 0; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
for (ti = Internal::Nikon1MakerNote::tagList(), idx = 0
|
||||
; ti[idx].tag_ != 0xffff; ++idx) tags[ti[idx].tag_] = ti[idx].name_;
|
||||
}
|
||||
init = false;
|
||||
|
||||
try {
|
||||
result = tags[tag].c_str();
|
||||
if ( nMaxLength > sizeof(buffer) -2 )
|
||||
nMaxLength = sizeof(buffer) -2;
|
||||
strncpy(buffer,result,nMaxLength);
|
||||
result = buffer;
|
||||
} catch ( ... ) {}
|
||||
|
||||
return result ;
|
||||
}
|
||||
|
||||
AccessMode ImageFactory::checkMode(int type, MetadataId metadataId)
|
||||
{
|
||||
const Registry* r = find(registry, type);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user