--- kfile-plugins/jpeg/exif.h
+++ kfile-plugins/jpeg/exif.h
@@ -72,7 +72,8 @@
     int Get32s(void * Long);
     unsigned Get32u(void * Long);
     double ConvertAnyFormat(void * ValuePtr, int Format);
-    void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength);
+    void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength,
+            unsigned NestingLevel);
     void process_COM (const uchar * Data, int length);
     void process_SOFn (const uchar * Data, int marker);
     int Get16m(const void * Short);
--- kfile-plugins/jpeg/exif.cpp
+++ kfile-plugins/jpeg/exif.cpp
@@ -446,7 +446,7 @@
 //--------------------------------------------------------------------------
 // Process one of the nested EXIF directories.
 //--------------------------------------------------------------------------
-void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength)
+void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, unsigned NestingLevel)
 {
     int de;
     int a;
@@ -454,6 +454,9 @@
     unsigned ThumbnailOffset = 0;
     unsigned ThumbnailSize = 0;
 
+    if ( NestingLevel > 4)
+        throw FatalError("Maximum directory nesting exceeded (corrupt exif header)");
+
     NumDirEntries = Get16u(DirStart);
     #define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))
 
@@ -476,7 +479,7 @@
     for (de=0;de<NumDirEntries;de++){
         int Tag, Format, Components;
         unsigned char * ValuePtr;
-        int ByteCount;
+        unsigned ByteCount;
         char * DirEntry;
         DirEntry = (char *)DIR_ENTRY_ADDR(DirStart, de);
 
@@ -489,6 +492,11 @@
             throw FatalError("Illegal format code in EXIF dir");
         }
 
+        if ((unsigned)Components > 0x10000) {
+            throw FatalError("Illegal number of components for tag");
+            continue;
+        }
+
         ByteCount = Components * BytesPerFormat[Format];
 
         if (ByteCount > 4){
@@ -517,11 +525,11 @@
         switch(Tag){
 
             case TAG_MAKE:
-                ExifData::CameraMake = QString((char*)ValuePtr);
+                ExifData::CameraMake = QString::fromLatin1((const char*)ValuePtr, 31);
                 break;
 
             case TAG_MODEL:
-                ExifData::CameraModel = QString((char*)ValuePtr);
+                ExifData::CameraModel = QString::fromLatin1((const char*)ValuePtr, 39);
 		break;
 
             case TAG_ORIENTATION:
@@ -529,7 +537,7 @@
                 break;
 
             case TAG_DATETIME_ORIGINAL:
-		DateTime = QString((char*)ValuePtr);
+		DateTime = QString::fromLatin1((const char*)ValuePtr, 19);
                 break;
 
             case TAG_USERCOMMENT:
@@ -550,14 +558,12 @@
                         int c;
                         c = (ValuePtr)[a];
                         if (c != '\0' && c != ' '){
-                            //strncpy(ImageInfo.Comments, (const char*)(a+ValuePtr), 199);
-                            UserComment.sprintf("%s", (const char*)(a+ValuePtr));
+                            UserComment = QString::fromLatin1((const char*)(a+ValuePtr), 199);
                             break;
                         }
                     }
                 }else{
-                    //strncpy(ImageInfo.Comments, (const char*)ValuePtr, 199);
-                    UserComment.sprintf("%s", (const char*)ValuePtr);
+                    UserComment = QString::fromLatin1((const char*)ValuePtr, 199);
                 }
                 break;
 
@@ -676,10 +682,10 @@
         if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
             unsigned char * SubdirStart;
             SubdirStart = OffsetBase + Get32u(ValuePtr);
-            if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength){
+            if (SubdirStart <= OffsetBase || SubdirStart >= OffsetBase+ExifLength){
                 throw FatalError("Illegal subdirectory link");
             }
-            ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
+            ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
             continue;
         }
     }
@@ -709,7 +715,7 @@
                     }
                 }else{
                     if (SubdirStart <= OffsetBase+ExifLength){
-                        ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
+                        ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
                     }
                 }
             }
@@ -719,7 +725,7 @@
     }
 
     if (ThumbnailSize && ThumbnailOffset){
-        if (ThumbnailSize + ThumbnailOffset <= ExifLength){
+        if (ThumbnailSize + ThumbnailOffset < ExifLength){
             // The thumbnail pointer appears to be valid.  Store it.
 	    Thumbnail.loadFromData(OffsetBase + ThumbnailOffset, ThumbnailSize, "JPEG");
         }
@@ -810,7 +816,7 @@
     LastExifRefd = CharBuf;
 
     // First directory starts 16 bytes in.  Offsets start at 8 bytes in.
-    ProcessExifDir(CharBuf+16, CharBuf+8, length-6);
+    ProcessExifDir(CharBuf+16, CharBuf+8, length-6, 0);
 
     // This is how far the interesting (non thumbnail) part of the exif went.
     ExifSettingsLength = LastExifRefd - CharBuf;