Bug Summary

File:/boot/home/haiku/haiku/src/add-ons/translators/icns/ICNSLoader.cpp
Location:line 180, column 2
Description:Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'

Annotated Source Code

1/*
2 * Copyright 2012, Gerasim Troeglazov, 3dEyes@gmail.com. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "ICNSLoader.h"
7#include "BaseTranslator.h"
8
9
10static int compareTypes(const void *a, const void *b)
11{
12 icns_type_t typeItemA = *((icns_type_t*)(*((icns_type_t*)a)));
13 icns_type_t typeItemB = *((icns_type_t*)(*((icns_type_t*)b)));
14
15 icns_icon_info_t imageInfoA = icns_get_image_info_for_type(typeItemA);
16 icns_icon_info_t imageInfoB = icns_get_image_info_for_type(typeItemB);
17
18 return imageInfoB.iconWidth - imageInfoA.iconWidth;
19}
20
21
22icns_type_t
23ICNSFormat(float width, float height, color_space colors)
24{
25 int imageWidth = (int)ceil(width);
26 int imageHeight = (int)ceil(height);
27
28 if (imageWidth != imageHeight)
29 return ICNS_NULL_TYPE0x00000000;
30
31 //other colors depth not supported now
32 if (colors != B_RGB32 && colors != B_RGBA32)
33 return ICNS_NULL_TYPE0x00000000;
34
35 switch (imageWidth) {
36 case 16:
37 return ICNS_16x16_32BIT_DATA0x69733332;
38 case 32:
39 return ICNS_32x32_32BIT_DATA0x696C3332;
40 case 48:
41 return ICNS_48x48_32BIT_DATA0x69683332;
42 case 128:
43 return ICNS_128X128_32BIT_DATA0x69743332;
44 case 256:
45 return ICNS_256x256_32BIT_ARGB_DATA0x69633038;
46 case 512:
47 return ICNS_512x512_32BIT_ARGB_DATA0x69633039;
48 case 1024:
49 return ICNS_1024x1024_32BIT_ARGB_DATA0x69633130;
50 }
51 return ICNS_NULL_TYPE0x00000000;
52}
53
54
55ICNSLoader::ICNSLoader(BPositionIO *stream)
56{
57 fLoaded = false;
58 fIconsCount = 0;
59
60 stream->Seek(0, SEEK_END2);
61 fStreamSize = stream->Position();
62 stream->Seek(0, SEEK_SET0);
63
64 if (fStreamSize <= 0)
65 return;
66
67 uint8* icnsDataBuffer = new uint8[fStreamSize];
68 size_t readedBytes = stream->Read(icnsDataBuffer,fStreamSize);
69
70 fIconFamily = NULL__null;
71 int status = icns_import_family_data(readedBytes, icnsDataBuffer,
72 &fIconFamily);
73
74 if (status != 0) {
75 delete icnsDataBuffer;
76 return;
77 }
78
79 icns_byte_t *dataPtr = (icns_byte_t*)fIconFamily;
80 off_t dataOffset = sizeof(icns_type_t) + sizeof(icns_size_t);
81
82 while ((dataOffset+8) < fIconFamily->resourceSize)
83 {
84 icns_element_t iconElement;
85 icns_size_t iconDataSize;
86
87 memcpy(&iconElement, (dataPtr + dataOffset), 8);
88 iconDataSize = iconElement.elementSize - 8;
89
90 if(IS_SPUPPORTED_TYPE(iconElement.elementType)((iconElement.elementType) == 0x69633130 || (iconElement.elementType
) == 0x69633039 || (iconElement.elementType) == 0x69633038 ||
(iconElement.elementType) == 0x69743332 || (iconElement.elementType
) == 0x69683332 || (iconElement.elementType) == 0x696C3332 ||
(iconElement.elementType) == 0x69733332)
) {
91 icns_type_t* newTypeItem = new icns_type_t;
92 *newTypeItem = iconElement.elementType;
93 fFormatList.AddItem(newTypeItem);
94 fIconsCount++;
95 }
96 dataOffset += iconElement.elementSize;
97 }
98
99 fFormatList.SortItems(compareTypes);
100
101 delete icnsDataBuffer;
102
103 fLoaded = true;
104}
105
106
107ICNSLoader::~ICNSLoader()
108{
109 if (fIconFamily != NULL__null)
110 free(fIconFamily);
111
112 icns_type_t* item;
113 for (int32 i = 0; (item = (icns_type_t*)fFormatList.ItemAt(i)) != NULL__null; i++)
114 delete item;
115 fFormatList.MakeEmpty();
116}
117
118
119bool
120ICNSLoader::IsLoaded(void)
121{
122 return fLoaded;
123}
124
125
126int
127ICNSLoader::IconsCount(void)
128{
129 return fIconsCount;
130}
131
132
133int
134ICNSLoader::GetIcon(BPositionIO *target, int index)
135{
136 if (index < 1 || index > fIconsCount || !fLoaded)
1
Assuming 'index' is >= 1
2
Taking false branch
137 return B_NO_TRANSLATOR(((-2147483647 - 1) + 0x4800) + 1);
138
139 icns_image_t iconImage;
140 memset(&iconImage, 0, sizeof(icns_image_t));
141
142 icns_type_t typeItem = *((icns_type_t*)fFormatList.ItemAt(index - 1));
143 int status = icns_get_image32_with_mask_from_family(fIconFamily,
144 typeItem, &iconImage);
145
146 if (status != 0)
3
Assuming 'status' is equal to 0
4
Taking false branch
147 return B_NO_TRANSLATOR(((-2147483647 - 1) + 0x4800) + 1);
148
149 TranslatorBitmap bitsHeader;
150 bitsHeader.magic = B_TRANSLATOR_BITMAP;
151 bitsHeader.bounds.left = 0;
152 bitsHeader.bounds.top = 0;
153 bitsHeader.bounds.right = iconImage.imageWidth - 1;
154 bitsHeader.bounds.bottom = iconImage.imageHeight - 1;
155 bitsHeader.rowBytes = sizeof(uint32) * iconImage.imageWidth;
156 bitsHeader.colors = B_RGBA32;
157 bitsHeader.dataSize = bitsHeader.rowBytes * iconImage.imageHeight;
158 if (swap_data(B_UINT32_TYPE, &bitsHeader,
5
Taking false branch
159 sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN) != B_OK((int)0)) {
160 icns_free_image(&iconImage);
161 return B_NO_TRANSLATOR(((-2147483647 - 1) + 0x4800) + 1);
162 }
163 target->Write(&bitsHeader, sizeof(TranslatorBitmap));
164
165 uint8 *rowBuff = new uint8[iconImage.imageWidth * sizeof(uint32)];
6
Memory is allocated
166 for (uint32 i = 0; i < iconImage.imageHeight; i++) {
7
Loop condition is false. Execution continues on line 180
167 uint8 *rowData = iconImage.imageData
168 + (i * iconImage.imageWidth * sizeof(uint32));
169 uint8 *rowBuffPtr = rowBuff;
170 for (uint32 j=0; j < iconImage.imageWidth; j++) {
171 rowBuffPtr[0] = rowData[2];
172 rowBuffPtr[1] = rowData[1];
173 rowBuffPtr[2] = rowData[0];
174 rowBuffPtr[3] = rowData[3];
175 rowBuffPtr += sizeof(uint32);
176 rowData += sizeof(uint32);
177 }
178 target->Write(rowBuff, iconImage.imageWidth * sizeof(uint32));
179 }
180 delete rowBuff;
8
Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'
181 icns_free_image(&iconImage);
182
183 return B_OK((int)0);
184}
185
186
187ICNSSaver::ICNSSaver(BPositionIO *stream, uint32 rowBytes, icns_type_t type)
188{
189 fCreated = false;
190
191 icns_icon_info_t imageTypeInfo = icns_get_image_info_for_type(type);
192 int iconWidth = imageTypeInfo.iconWidth;
193 int iconHeight = imageTypeInfo.iconWidth;
194 int bpp = 32;
195
196 uint8 *bits = new uint8[iconWidth * iconHeight * sizeof(uint32)];
197
198 uint8 *rowPtr = bits;
199 for (int i = 0; i < iconHeight; i++) {
200 stream->Read(rowPtr, rowBytes);
201 uint8 *bytePtr = rowPtr;
202 for (int j=0; j < iconWidth; j++) {
203 uint8 temp = bytePtr[0];
204 bytePtr[0] = bytePtr[2];
205 bytePtr[2] = temp;
206 bytePtr += sizeof(uint32);
207 }
208 rowPtr += iconWidth * sizeof(uint32);
209 }
210
211 icns_create_family(&fIconFamily);
212
213 icns_image_t icnsImage;
214 icnsImage.imageWidth = iconWidth;
215 icnsImage.imageHeight = iconHeight;
216 icnsImage.imageChannels = 4;
217 icnsImage.imagePixelDepth = 8;
218 icnsImage.imageDataSize = iconWidth * iconHeight * 4;
219 icnsImage.imageData = bits;
220
221 icns_icon_info_t iconInfo;
222 iconInfo.isImage = 1;
223 iconInfo.iconWidth = icnsImage.imageWidth;
224 iconInfo.iconHeight = icnsImage.imageHeight;
225 iconInfo.iconBitDepth = bpp;
226 iconInfo.iconChannels = (bpp == 32 ? 4 : 1);
227 iconInfo.iconPixelDepth = bpp / iconInfo.iconChannels;
228
229 icns_type_t iconType = icns_get_type_from_image_info(iconInfo);
230
231 if (iconType == ICNS_NULL_TYPE0x00000000) {
232 delete bits;
233 free(fIconFamily);
234 fIconFamily = NULL__null;
235 return;
236 }
237
238 icns_element_t *iconElement = NULL__null;
239 int icnsErr = icns_new_element_from_image(&icnsImage, iconType,
240 &iconElement);
241
242 if (iconElement != NULL__null) {
243 if (icnsErr == ICNS_STATUS_OK0) {
244 icns_set_element_in_family(&fIconFamily, iconElement);
245 fCreated = true;
246 }
247 free(iconElement);
248 }
249
250 if (iconType != ICNS_1024x1024_32BIT_ARGB_DATA0x69633130
251 && iconType != ICNS_512x512_32BIT_ARGB_DATA0x69633039
252 && iconType != ICNS_256x256_32BIT_ARGB_DATA0x69633038)
253 {
254 icns_type_t maskType = icns_get_mask_type_for_icon_type(iconType);
255
256 icns_image_t icnsMask;
257 icns_init_image_for_type(maskType, &icnsMask);
258
259 uint32 iconDataOffset = 0;
260 uint32 maskDataOffset = 0;
261
262 while (iconDataOffset < icnsImage.imageDataSize
263 && maskDataOffset < icnsMask.imageDataSize) {
264 icnsMask.imageData[maskDataOffset] =
265 icnsImage.imageData[iconDataOffset + 3];
266 iconDataOffset += 4;
267 maskDataOffset += 1;
268 }
269
270 icns_element_t *maskElement = NULL__null;
271 icnsErr = icns_new_element_from_mask(&icnsMask, maskType,
272 &maskElement);
273
274 if (maskElement != NULL__null) {
275 if (icnsErr == ICNS_STATUS_OK0)
276 icns_set_element_in_family(&fIconFamily, maskElement);
277 else
278 fCreated = false;
279 free(maskElement);
280 }
281 icns_free_image(&icnsMask);
282 }
283
284 if (!fCreated) {
285 free(fIconFamily);
286 fIconFamily = NULL__null;
287 }
288
289 delete bits;
290}
291
292
293ICNSSaver::~ICNSSaver()
294{
295 if (fIconFamily != NULL__null)
296 free(fIconFamily);
297}
298
299
300int
301ICNSSaver::SaveData(BPositionIO *target)
302{
303 icns_size_t dataSize;
304 icns_byte_t *dataPtrOut;
305 icns_export_family_data(fIconFamily, &dataSize, &dataPtrOut);
306 if (dataSize != 0 && dataPtrOut != NULL__null) {
307 if (target->Write(dataPtrOut, dataSize) == dataSize);
308 return B_OK((int)0);
309 }
310 return B_ERROR(-1);
311}
312
313
314bool
315ICNSSaver::IsCreated(void)
316{
317 return fCreated;
318}