Bug Summary

File:src/servers/app/drawing/interface/remote/RemoteMessage.cpp
Warning:line 506, column 11
Potential leak of memory pointed to by 'gradient'

Annotated Source Code

1/*
2 * Copyright 2009, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Michael Lotz <mmlr@mlotz.ch>
7 */
8
9#include "RemoteMessage.h"
10
11#ifndef CLIENT_COMPILE1
12#include "DrawState.h"
13#include "ServerBitmap.h"
14#include "ServerCursor.h"
15#endif
16
17#include <Bitmap.h>
18#include <Font.h>
19#include <View.h>
20
21#include <Gradient.h>
22#include <GradientLinear.h>
23#include <GradientRadial.h>
24#include <GradientRadialFocus.h>
25#include <GradientDiamond.h>
26#include <GradientConic.h>
27
28#include <new>
29
30
31status_t
32RemoteMessage::NextMessage(uint16& code)
33{
34 if (fDataLeft > 0) {
35 // discard remainder of message
36 int32 readSize = fSource->Read(NULL__null, fDataLeft);
37 if (readSize < 0)
38 return readSize;
39 }
40
41 static const uint32 kHeaderSize = sizeof(uint16) + sizeof(uint32);
42
43 fDataLeft = kHeaderSize;
44 Read(code);
45 uint32 dataLeft;
46 status_t result = Read(dataLeft);
47 if (result != B_OK((int)0))
48 return result;
49
50 if (dataLeft < kHeaderSize)
51 return B_ERROR(-1);
52
53 fDataLeft = dataLeft - kHeaderSize;
54 fCode = code;
55 return B_OK((int)0);
56}
57
58
59void
60RemoteMessage::Cancel()
61{
62 fAvailable += fWriteIndex;
63 fWriteIndex = 0;
64}
65
66
67#ifndef CLIENT_COMPILE1
68void
69RemoteMessage::AddBitmap(const ServerBitmap& bitmap, bool minimal)
70{
71 Add(bitmap.Width());
72 Add(bitmap.Height());
73 Add(bitmap.BytesPerRow());
74
75 if (!minimal) {
76 Add(bitmap.ColorSpace());
77 Add(bitmap.Flags());
78 }
79
80 uint32 bitsLength = bitmap.BitsLength();
81 Add(bitsLength);
82
83 if (!_MakeSpace(bitsLength))
84 return;
85
86 memcpy(fBuffer + fWriteIndex, bitmap.Bits(), bitsLength);
87 fWriteIndex += bitsLength;
88 fAvailable -= bitsLength;
89}
90
91
92void
93RemoteMessage::AddFont(const ServerFont& font)
94{
95 Add(font.Direction());
96 Add((uint8)font.Encoding());
97 Add(font.Flags());
98 Add((uint8)font.Spacing());
99 Add(font.Shear());
100 Add(font.Rotation());
101 Add(font.FalseBoldWidth());
102 Add(font.Size());
103 Add(font.Face());
104 Add(font.GetFamilyAndStyle());
105}
106
107
108void
109RemoteMessage::AddDrawState(const DrawState& drawState)
110{
111 Add(drawState.PenSize());
112 Add(drawState.SubPixelPrecise());
113 Add(drawState.GetDrawingMode());
114 Add(drawState.AlphaSrcMode());
115 Add(drawState.AlphaFncMode());
116 AddPattern(drawState.GetPattern());
117 Add(drawState.LineCapMode());
118 Add(drawState.LineJoinMode());
119 Add(drawState.MiterLimit());
120 Add(drawState.HighColor());
121 Add(drawState.LowColor());
122}
123
124
125void
126RemoteMessage::AddArrayLine(const ViewLineArrayInfo& line)
127{
128 Add(line.startPoint);
129 Add(line.endPoint);
130 Add(line.color);
131}
132
133
134void
135RemoteMessage::AddCursor(const ServerCursor& cursor)
136{
137 Add(cursor.GetHotSpot());
138 AddBitmap(cursor);
139}
140
141
142void
143RemoteMessage::AddPattern(const Pattern& pattern)
144{
145 Add(pattern.GetPattern());
146}
147
148#else // !CLIENT_COMPILE
149
150void
151RemoteMessage::AddBitmap(const BBitmap& bitmap)
152{
153 BRect bounds = bitmap.Bounds();
154 Add(bounds.IntegerWidth() + 1);
155 Add(bounds.IntegerHeight() + 1);
156 Add(bitmap.BytesPerRow());
157 Add(bitmap.ColorSpace());
158 Add(bitmap.Flags());
159
160 uint32 bitsLength = bitmap.BitsLength();
161 Add(bitsLength);
162
163 if (!_MakeSpace(bitsLength))
164 return;
165
166 memcpy(fBuffer + fWriteIndex, bitmap.Bits(), bitsLength);
167 fWriteIndex += bitsLength;
168 fAvailable -= bitsLength;
169}
170#endif // !CLIENT_COMPILE
171
172
173void
174RemoteMessage::AddGradient(const BGradient& gradient)
175{
176 Add(gradient.GetType());
177
178 switch (gradient.GetType()) {
179 case BGradient::TYPE_NONE:
180 break;
181
182 case BGradient::TYPE_LINEAR:
183 {
184 const BGradientLinear* linear
185 = dynamic_cast<const BGradientLinear *>(&gradient);
186 if (linear == NULL__null)
187 return;
188
189 Add(linear->Start());
190 Add(linear->End());
191 break;
192 }
193
194 case BGradient::TYPE_RADIAL:
195 {
196 const BGradientRadial* radial
197 = dynamic_cast<const BGradientRadial *>(&gradient);
198 if (radial == NULL__null)
199 return;
200
201 Add(radial->Center());
202 Add(radial->Radius());
203 break;
204 }
205
206 case BGradient::TYPE_RADIAL_FOCUS:
207 {
208 const BGradientRadialFocus* radialFocus
209 = dynamic_cast<const BGradientRadialFocus *>(&gradient);
210 if (radialFocus == NULL__null)
211 return;
212
213 Add(radialFocus->Center());
214 Add(radialFocus->Focal());
215 Add(radialFocus->Radius());
216 break;
217 }
218
219 case BGradient::TYPE_DIAMOND:
220 {
221 const BGradientDiamond* diamond
222 = dynamic_cast<const BGradientDiamond *>(&gradient);
223 if (diamond == NULL__null)
224 return;
225
226 Add(diamond->Center());
227 break;
228 }
229
230 case BGradient::TYPE_CONIC:
231 {
232 const BGradientConic* conic
233 = dynamic_cast<const BGradientConic *>(&gradient);
234 if (conic == NULL__null)
235 return;
236
237 Add(conic->Center());
238 Add(conic->Angle());
239 break;
240 }
241 }
242
243 int32 stopCount = gradient.CountColorStops();
244 Add(stopCount);
245
246 for (int32 i = 0; i < stopCount; i++) {
247 BGradient::ColorStop* stop = gradient.ColorStopAt(i);
248 if (stop == NULL__null)
249 return;
250
251 Add(stop->color);
252 Add(stop->offset);
253 }
254}
255
256
257status_t
258RemoteMessage::ReadString(char** _string, size_t& _length)
259{
260 uint32 length;
261 status_t result = Read(length);
262 if (result != B_OK((int)0))
263 return result;
264
265 if (length > fDataLeft)
266 return B_ERROR(-1);
267
268 char *string = (char *)malloc(length + 1);
269 if (string == NULL__null)
270 return B_NO_MEMORY((-2147483647 - 1) + 0);
271
272 int32 readSize = fSource->Read(string, length);
273 if (readSize < 0) {
274 free(string);
275 return readSize;
276 }
277
278 if ((uint32)readSize != length) {
279 free(string);
280 return B_ERROR(-1);
281 }
282
283 fDataLeft -= readSize;
284
285 string[length] = 0;
286 *_string = string;
287 _length = length;
288 return B_OK((int)0);
289}
290
291
292status_t
293RemoteMessage::ReadBitmap(BBitmap** _bitmap, bool minimal,
294 color_space colorSpace, uint32 flags)
295{
296 uint32 bitsLength;
297 int32 width, height, bytesPerRow;
298
299 Read(width);
300 Read(height);
301 Read(bytesPerRow);
302
303 if (!minimal) {
304 Read(colorSpace);
305 Read(flags);
306 }
307
308 Read(bitsLength);
309
310 if (bitsLength > fDataLeft)
311 return B_ERROR(-1);
312
313#ifndef CLIENT_COMPILE1
314 flags = B_BITMAP_NO_SERVER_LINK;
315#endif
316
317 BBitmap *bitmap = new(std::nothrow) BBitmap(
318 BRect(0, 0, width - 1, height - 1), flags, colorSpace, bytesPerRow);
319 if (bitmap == NULL__null)
320 return B_NO_MEMORY((-2147483647 - 1) + 0);
321
322 status_t result = bitmap->InitCheck();
323 if (result != B_OK((int)0)) {
324 delete bitmap;
325 return result;
326 }
327
328 if (bitmap->BitsLength() < (int32)bitsLength) {
329 delete bitmap;
330 return B_ERROR(-1);
331 }
332
333 int32 readSize = fSource->Read(bitmap->Bits(), bitsLength);
334 if ((uint32)readSize != bitsLength) {
335 delete bitmap;
336 return readSize < 0 ? readSize : B_ERROR(-1);
337 }
338
339 fDataLeft -= readSize;
340 *_bitmap = bitmap;
341 return B_OK((int)0);
342}
343
344
345status_t
346RemoteMessage::ReadFontState(BFont& font)
347{
348 uint8 encoding, spacing;
349 uint16 face;
350 uint32 flags, familyAndStyle;
351 font_direction direction;
352 float falseBoldWidth, rotation, shear, size;
353
354 Read(direction);
355 Read(encoding);
356 Read(flags);
357 Read(spacing);
358 Read(shear);
359 Read(rotation);
360 Read(falseBoldWidth);
361 Read(size);
362 Read(face);
363 status_t result = Read(familyAndStyle);
364 if (result != B_OK((int)0))
365 return result;
366
367 font.SetFamilyAndStyle(familyAndStyle);
368 font.SetEncoding(encoding);
369 font.SetFlags(flags);
370 font.SetSpacing(spacing);
371 font.SetShear(shear);
372 font.SetRotation(rotation);
373 font.SetFalseBoldWidth(falseBoldWidth);
374 font.SetSize(size);
375 font.SetFace(face);
376 return B_OK((int)0);
377}
378
379
380status_t
381RemoteMessage::ReadViewState(BView& view, ::pattern& pattern)
382{
383 bool subPixelPrecise;
384 float penSize, miterLimit;
385 drawing_mode drawingMode;
386 source_alpha sourceAlpha;
387 alpha_function alphaFunction;
388 cap_mode capMode;
389 join_mode joinMode;
390 rgb_color highColor, lowColor;
391
392 Read(penSize);
393 Read(subPixelPrecise);
394 Read(drawingMode);
395 Read(sourceAlpha);
396 Read(alphaFunction);
397 Read(pattern);
398 Read(capMode);
399 Read(joinMode);
400 Read(miterLimit);
401 Read(highColor);
402 status_t result = Read(lowColor);
403 if (result != B_OK((int)0))
404 return result;
405
406 uint32 flags = view.Flags() & ~B_SUBPIXEL_PRECISE;
407 view.SetFlags(flags | (subPixelPrecise ? B_SUBPIXEL_PRECISE : 0));
408 view.SetPenSize(penSize);
409 view.SetDrawingMode(drawingMode);
410 view.SetBlendingMode(sourceAlpha, alphaFunction);
411 view.SetLineMode(capMode, joinMode, miterLimit);
412 view.SetHighColor(highColor);
413 view.SetLowColor(lowColor);
414 return B_OK((int)0);
415}
416
417
418status_t
419RemoteMessage::ReadGradient(BGradient** _gradient)
420{
421 BGradient::Type type;
422 Read(type);
423
424 BGradient *gradient = NULL__null;
425 switch (type) {
1
Control jumps to 'case TYPE_CONIC:' at line 476
426 case BGradient::TYPE_NONE:
427 break;
428
429 case BGradient::TYPE_LINEAR:
430 {
431 BPoint start, end;
432
433 Read(start);
434 Read(end);
435
436 gradient = new(std::nothrow) BGradientLinear(start, end);
437 break;
438 }
439
440 case BGradient::TYPE_RADIAL:
441 {
442 BPoint center;
443 float radius;
444
445 Read(center);
446 Read(radius);
447
448 gradient = new(std::nothrow) BGradientRadial(center, radius);
449 break;
450 }
451
452 case BGradient::TYPE_RADIAL_FOCUS:
453 {
454 BPoint center, focal;
455 float radius;
456
457 Read(center);
458 Read(focal);
459 Read(radius);
460
461 gradient = new(std::nothrow) BGradientRadialFocus(center, radius,
462 focal);
463 break;
464 }
465
466 case BGradient::TYPE_DIAMOND:
467 {
468 BPoint center;
469
470 Read(center);
471
472 gradient = new(std::nothrow) BGradientDiamond(center);
473 break;
474 }
475
476 case BGradient::TYPE_CONIC:
477 {
478 BPoint center;
479 float angle;
480
481 Read(center);
482 Read(angle);
483
484 gradient = new(std::nothrow) BGradientConic(center, angle);
2
Memory is allocated
485 break;
3
Execution continues on line 489
486 }
487 }
488
489 if (gradient == NULL__null)
4
Assuming 'gradient' is not equal to NULL
5
Taking false branch
490 return B_NO_MEMORY((-2147483647 - 1) + 0);
491
492 int32 stopCount;
493 status_t result = Read(stopCount);
494 if (result != B_OK((int)0)) {
6
Taking false branch
495 delete gradient;
496 return result;
497 }
498
499 for (int32 i = 0; i < stopCount; i++) {
7
Assuming 'i' is < 'stopCount'
8
Loop condition is true. Entering loop body
500 rgb_color color;
501 float offset;
502
503 Read(color);
504 result = Read(offset);
505 if (result != B_OK((int)0))
9
Taking true branch
506 return result;
10
Potential leak of memory pointed to by 'gradient'
507
508 gradient->AddColor(color, offset);
509 }
510
511 *_gradient = gradient;
512 return B_OK((int)0);
513}
514
515
516status_t
517RemoteMessage::ReadArrayLine(BPoint& startPoint, BPoint& endPoint,
518 rgb_color& color)
519{
520 Read(startPoint);
521 Read(endPoint);
522 return Read(color);
523}