vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / translators / hvif / HVIFTranslator.cpp
blob78f52a4587f2513ac8c92e77e1f849a02d1b6502
1 /*
2 * Copyright 2009, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
5 * Authors:
6 * Michael Lotz, mmlr@mlotz.ch
7 */
9 #include "HVIFTranslator.h"
10 #include "HVIFView.h"
12 #include <Bitmap.h>
13 #include <BitmapStream.h>
14 #include <Catalog.h>
15 #include <IconUtils.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
21 #define HVIF_FORMAT_CODE 'HVIF'
22 #define HVIF_TRANSLATION_QUALITY 1.0
23 #define HVIF_TRANSLATION_CAPABILITY 1.0
25 #undef B_TRANSLATION_CONTEXT
26 #define B_TRANSLATION_CONTEXT "HVIFTranslator"
29 static const translation_format sInputFormats[] = {
31 HVIF_FORMAT_CODE,
32 B_TRANSLATOR_BITMAP,
33 HVIF_TRANSLATION_QUALITY,
34 HVIF_TRANSLATION_CAPABILITY,
35 "application/x-vnd.Haiku-icon",
36 "Native Haiku vector icon"
41 static const translation_format sOutputFormats[] = {
43 B_TRANSLATOR_BITMAP,
44 B_TRANSLATOR_BITMAP,
45 0.4,
46 0.4,
47 "image/x-be-bitmap",
48 "Be Bitmap format (HVIFTranslator)"
53 static const TranSetting sDefaultSettings[] = {
54 { HVIF_SETTING_RENDER_SIZE, TRAN_SETTING_INT32, 64 }
57 const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format);
58 const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format);
59 const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting);
63 BTranslator *
64 make_nth_translator(int32 n, image_id image, uint32 flags, ...)
66 if (n == 0)
67 return new HVIFTranslator();
68 return NULL;
72 HVIFTranslator::HVIFTranslator()
73 : BaseTranslator(B_TRANSLATE("HVIF icons"),
74 B_TRANSLATE("Haiku vector icon translator"),
75 HVIF_TRANSLATOR_VERSION,
76 sInputFormats, kNumInputFormats,
77 sOutputFormats, kNumOutputFormats,
78 "HVIFTranslator_Settings",
79 sDefaultSettings, kNumDefaultSettings,
80 B_TRANSLATOR_BITMAP, HVIF_FORMAT_CODE)
85 HVIFTranslator::~HVIFTranslator()
90 status_t
91 HVIFTranslator::DerivedIdentify(BPositionIO *inSource,
92 const translation_format *inFormat, BMessage *ioExtension,
93 translator_info *outInfo, uint32 outType)
95 // TODO: we do the fully work twice!
96 if (outType != B_TRANSLATOR_BITMAP)
97 return B_NO_TRANSLATOR;
99 // filter out invalid sizes
100 off_t size = inSource->Seek(0, SEEK_END);
101 if (size <= 0 || size > 256 * 1024 || inSource->Seek(0, SEEK_SET) != 0)
102 return B_NO_TRANSLATOR;
104 uint8 *buffer = (uint8 *)malloc(size);
105 if (buffer == NULL)
106 return B_NO_MEMORY;
108 if (inSource->Read(buffer, size) != size) {
109 free(buffer);
110 return B_NO_TRANSLATOR;
113 BBitmap dummy(BRect(0, 0, 1, 1), B_BITMAP_NO_SERVER_LINK, B_RGBA32);
114 if (BIconUtils::GetVectorIcon(buffer, size, &dummy) != B_OK) {
115 free(buffer);
116 return B_NO_TRANSLATOR;
119 if (outInfo) {
120 outInfo->type = sInputFormats[0].type;
121 outInfo->group = sInputFormats[0].group;
122 outInfo->quality = sInputFormats[0].quality;
123 outInfo->capability = sInputFormats[0].capability;
124 strcpy(outInfo->MIME, sInputFormats[0].MIME);
125 strcpy(outInfo->name, sInputFormats[0].name);
128 free(buffer);
129 return B_OK;
133 status_t
134 HVIFTranslator::DerivedTranslate(BPositionIO *inSource,
135 const translator_info *inInfo, BMessage *ioExtension, uint32 outType,
136 BPositionIO *outDestination, int32 baseType)
138 if (outType != B_TRANSLATOR_BITMAP)
139 return B_NO_TRANSLATOR;
141 // filter out invalid sizes
142 off_t size = inSource->Seek(0, SEEK_END);
143 if (size <= 0 || size > 256 * 1024 || inSource->Seek(0, SEEK_SET) != 0)
144 return B_NO_TRANSLATOR;
146 uint8 *buffer = (uint8 *)malloc(size);
147 if (buffer == NULL)
148 return B_NO_MEMORY;
150 if (inSource->Read(buffer, size) != size) {
151 free(buffer);
152 return B_NO_TRANSLATOR;
155 int32 renderSize = fSettings->SetGetInt32(HVIF_SETTING_RENDER_SIZE);
156 if (renderSize <= 0 || renderSize > 1024)
157 renderSize = 64;
159 BBitmap rendered(BRect(0, 0, renderSize - 1, renderSize - 1),
160 B_BITMAP_NO_SERVER_LINK, B_RGBA32);
161 if (BIconUtils::GetVectorIcon(buffer, size, &rendered) != B_OK) {
162 free(buffer);
163 return B_NO_TRANSLATOR;
166 BBitmapStream stream(&rendered);
167 stream.Seek(0, SEEK_SET);
168 ssize_t read = 0;
170 while ((read = stream.Read(buffer, size)) > 0)
171 outDestination->Write(buffer, read);
173 BBitmap *dummy = NULL;
174 stream.DetachBitmap(&dummy);
175 free(buffer);
176 return B_OK;
180 BView *
181 HVIFTranslator::NewConfigView(TranslatorSettings *settings)
183 return new HVIFView(B_TRANSLATE("HVIFTranslator Settings"),
184 B_WILL_DRAW, settings);