vfs: check userland buffers before reading them.
[haiku.git] / src / tests / add-ons / translators / exif / dump_exif.cpp
blob53040169dd14bdea1d8618bd9ee5d98432524ca6
1 /*
2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "exif_parser.h"
9 #include <stdio.h>
10 #include <string.h>
12 #include <BufferIO.h>
13 #include <Entry.h>
14 #include <File.h>
15 #include <Message.h>
17 #include "ReadHelper.h"
18 #include "TIFF.h"
21 static status_t
22 process_exif(uint8* data, uint32 length)
24 if (memcmp(data + 2, "Exif", 4))
25 return B_BAD_TYPE;
27 BMemoryIO source(data + 8, length - 8);
28 BMessage exif;
29 status_t status = convert_exif_to_message(source, exif);
31 exif.PrintToStream();
32 // even if it failed, some data might end up in the message
34 return status;
38 static status_t
39 process_jpeg(BPositionIO& stream)
41 enum {
42 START_OF_IMAGE_MARKER = 0xd8,
43 EXIF_MARKER = 0xe1
46 uint8 header[2];
47 if (stream.Read(&header, 2) != 2)
48 return B_IO_ERROR;
49 if (header[0] != 0xff || header[1] != START_OF_IMAGE_MARKER)
50 return B_BAD_TYPE;
52 while (true) {
53 // read marker
54 uint8 marker;
55 for (int32 i = 0; i < 7; i++) {
56 if (stream.Read(&marker, 1) != 1)
57 return B_BAD_TYPE;
59 if (marker != 0xff)
60 break;
63 if (marker == 0xff)
64 return B_BAD_TYPE;
66 // get length of section
68 uint16 length;
69 if (stream.Read(&length, 2) != 2)
70 return B_BAD_TYPE;
72 swap_data(B_UINT16_TYPE, &length, 2, B_SWAP_BENDIAN_TO_HOST);
74 if (marker == EXIF_MARKER) {
75 // read in section
76 stream.Seek(-2, SEEK_CUR);
78 uint8 exifData[length];
79 if (stream.Read(exifData, length) == length
80 && process_exif(exifData, length) == B_OK)
81 return B_OK;
82 } else {
83 // ignore section
84 stream.Seek(length - 2, SEEK_CUR);
88 return B_BAD_VALUE;
92 static status_t
93 process_file(entry_ref& ref)
95 BFile file(&ref, B_READ_WRITE);
96 status_t status = file.InitCheck();
97 if (status != B_OK)
98 return status;
100 // read EXIF
102 BBufferIO stream(&file, 65536, false);
103 status = process_jpeg(file);
104 if (status < B_OK) {
105 fprintf(stderr, "%s: processing JPEG file failed: %s\n", ref.name,
106 strerror(status));
107 return status;
110 return B_OK;
115 main(int argc, char **argv)
117 for (int i = 1; i < argc; i++) {
118 BEntry entry(argv[i]);
119 entry_ref ref;
120 if (entry.InitCheck() != B_OK || entry.GetRef(&ref) != B_OK)
121 continue;
123 process_file(ref);
125 return -1;