Changeset 25447

Show
Ignore:
Timestamp:
05/11/08 07:28:01 (6 days ago)
Author:
axeld
Message:
* The EXIF parser now keeps a set of visited offsets to avoid entering endless
  loops with corrupted data.
* This fixes bug #2206.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • haiku/trunk/src/add-ons/translators/jpeg/exif_parser.cpp

    r20633 r25447  
    11/* 
    2  * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 
     2 * Copyright 2007-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 
    33 * Distributed under the terms of the MIT License. 
    44 */ 
     
    77#include "exif_parser.h" 
    88 
    9 #include <ReadHelper.h> 
    10  
    11 #include <Message.h> 
    12  
    139#include <ctype.h> 
     10#include <set> 
    1411#include <stdio.h> 
    1512#include <stdlib.h> 
     13 
     14#include <Message.h> 
     15 
     16#include <ReadHelper.h> 
    1617 
    1718 
     
    3839 
    3940 
    40 static status_t parse_tiff_directory(TReadHelper& read, BMessage& target
    41         const convert_tag* tags, size_t tagCount); 
     41static status_t parse_tiff_directory(TReadHelper& read, set<off_t>& visited
     42        BMessage& target, const convert_tag* tags, size_t tagCount); 
    4243 
    4344 
     
    227228 
    228229static status_t 
    229 parse_tiff_directory(TReadHelper& read, off_t offset, BMessage& target, 
    230         const convert_tag* convertTags, size_t convertTagCount) 
    231 
     230parse_tiff_directory(TReadHelper& read, set<off_t>& visited, off_t offset, 
     231        BMessage& target, const convert_tag* convertTags, size_t convertTagCount) 
     232
     233        if (visited.find(offset) != visited.end()) { 
     234                // The EXIF data is obviously corrupt 
     235                return B_BAD_DATA; 
     236        } 
     237 
    232238        read.Seek(offset, SEEK_SET); 
     239        visited.insert(offset); 
    233240 
    234241        uint16 tags; 
     
    248255                        case TAG_SUB_DIR_OFFSET: 
    249256                        { 
    250                                 status_t status = parse_tiff_directory(read, target, 
     257                                status_t status = parse_tiff_directory(read, visited, target, 
    251258                                        convertTags, convertTagCount); 
    252259                                if (status < B_OK) 
     
    264271                                break; 
    265272                } 
     273 
     274                if (visited.find(nextOffset) != visited.end()) 
     275                        return B_BAD_DATA; 
     276 
    266277                read.Seek(nextOffset, SEEK_SET); 
     278                visited.insert(nextOffset); 
    267279        } 
    268280 
     
    272284 
    273285static status_t 
    274 parse_tiff_directory(TReadHelper& read, BMessage& target, 
     286parse_tiff_directory(TReadHelper& read, set<off_t>& visited, BMessage& target, 
    275287        const convert_tag* tags, size_t tagCount) 
    276288{ 
     
    281293                        break; 
    282294 
    283                 status_t status = parse_tiff_directory(read, offset, target, 
     295                status_t status = parse_tiff_directory(read, visited, offset, target, 
    284296                        tags, tagCount); 
    285297                if (status < B_OK) 
     
    294306 
    295307 
     308/*!     Converts the EXIF data that starts in \a source to a BMessage in \a target. 
     309        If the EXIF data is corrupt, this function will return an appropriate error 
     310        code. Nevertheless, there might be some data ending up in \a target that 
     311        was parsed until this point. 
     312*/ 
    296313status_t 
    297314convert_exif_to_message(BPositionIO& source, BMessage& target, 
     
    316333                return B_BAD_TYPE; 
    317334 
    318         return parse_tiff_directory(read, target, tags, tagCount); 
     335        set<off_t> visitedOffsets; 
     336        return parse_tiff_directory(read, visitedOffsets, target, tags, tagCount); 
    319337} 
    320338 
  • haiku/trunk/src/tests/add-ons/translators/exif/dump_exif.cpp

    r25446 r25447  
    2828        BMessage exif; 
    2929        status_t status = convert_exif_to_message(source, exif); 
    30         if (status == B_OK) 
    31                 exif.PrintToStream(); 
     30 
     31        exif.PrintToStream(); 
     32                // even if it failed, some data might end up in the message 
    3233 
    3334        return status;