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.
v0.27.3
Michał Walenciak 8 years ago
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…
Cancel
Save