diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 6aa188be0c..133e674598 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007, Haiku. + * Copyright 2001-2008, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -62,15 +62,14 @@ //#define DEBUG_SERVERAPP #ifdef DEBUG_SERVERAPP -# define STRACE(x) printf x +# define STRACE(x) debug_printf x #else # define STRACE(x) ; #endif //#define DEBUG_SERVERAPP_FONT - #ifdef DEBUG_SERVERAPP_FONT -# define FTRACE(x) printf x +# define FTRACE(x) debug_printf x #else # define FTRACE(x) ; #endif @@ -1414,6 +1413,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) size = 0.0f; } + // TODO: don't use the stack for this - numStrings could be large float widthArray[numStrings]; int32 lengthArray[numStrings]; char *stringArray[numStrings]; @@ -1599,6 +1599,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) link.Read(&numChars); link.Read(&numBytes); + // TODO: proper error checking char* charArray = new (nothrow) char[numBytes]; link.Read(charArray, numBytes); @@ -1611,6 +1612,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) font.SetFalseBoldWidth(falseBoldWidth); font.SetFlags(flags); + // TODO: proper error checking BShape** shapes = new (nothrow) BShape*[numChars]; status = font.GetGlyphShapes(charArray, numChars, shapes); if (status == B_OK) { @@ -1647,6 +1649,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) int32 numChars, numBytes; link.Read(&numChars); link.Read(&numBytes); + // TODO: proper error checking char* charArray = new (nothrow) char[numBytes]; link.Read(charArray, numBytes); @@ -1686,6 +1689,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) uint32 numBytes; link.Read(&numBytes); + // TODO: proper error checking char* charArray = new (nothrow) char[numBytes]; link.Read(charArray, numBytes); @@ -1748,7 +1752,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) uint32 numBytes; link.Read(&numBytes); + char *charArray = new (nothrow) char[numBytes]; + BPoint *escapements = new (nothrow) BPoint[numChars]; + BPoint *offsets = NULL; + if (wantsOffsets) + offsets = new (nothrow) BPoint[numChars]; + + if (charArray == NULL || escapements == NULL + || (offsets == NULL && wantsOffsets)) { + delete[] charArray; + delete[] escapements; + delete[] offsets; + + fLink.StartMessage(B_NO_MEMORY); + fLink.Flush(); + break; + } + link.Read(charArray, numBytes); ServerFont font; @@ -1759,20 +1780,15 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) font.SetRotation(rotation); font.SetFlags(flags); - BPoint *escapements = new (nothrow) BPoint[numChars]; - BPoint *offsets = NULL; - if (wantsOffsets) - offsets = new (nothrow) BPoint[numChars]; - - status = font.GetEscapements(charArray, numBytes, delta, - escapements, offsets); + status = font.GetEscapements(charArray, numBytes, numChars, + delta, escapements, offsets); if (status == B_OK) { fLink.StartMessage(B_OK); for (int32 i = 0; i < numChars; i++) fLink.Attach(escapements[i]); - if (wantsOffsets) { + if (offsets) { for (int32 i = 0; i < numChars; i++) fLink.Attach(offsets[i]); } @@ -1781,7 +1797,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) delete[] escapements; delete[] offsets; - } else fLink.StartMessage(status); @@ -1831,10 +1846,18 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) uint32 numBytes; link.Read(&numBytes); - char* charArray = new (nothrow) char[numBytes]; - link.Read(charArray, numBytes); + char* charArray = new (nothrow) char[numBytes]; float* escapements = new (nothrow) float[numChars]; + if (charArray == NULL || escapements == NULL) { + delete[] charArray; + delete[] escapements; + fLink.StartMessage(B_NO_MEMORY); + fLink.Flush(); + break; + } + + link.Read(charArray, numBytes); // figure out escapements @@ -1846,8 +1869,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) font.SetRotation(rotation); font.SetFlags(flags); - status = font.GetEscapements(charArray, numBytes, delta, - escapements); + status = font.GetEscapements(charArray, numBytes, numChars, + delta, escapements); if (status == B_OK) { fLink.StartMessage(B_OK); @@ -1917,6 +1940,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) uint32 numBytes; link.Read(&numBytes); + // TODO: proper error checking char *charArray = new (nothrow) char[numBytes]; link.Read(charArray, numBytes); @@ -2574,7 +2598,7 @@ ServerApp::_CreateWindow(int32 code, BPrivate::LinkReceiver& link, frame.bottom = frame.top + 1; } - status_t status = B_ERROR; + status_t status = B_NO_MEMORY; ServerWindow *window = NULL; if (code == AS_CREATE_OFFSCREEN_WINDOW) { @@ -2583,7 +2607,8 @@ ServerApp::_CreateWindow(int32 code, BPrivate::LinkReceiver& link, if (bitmap != NULL) { window = new (nothrow) OffscreenServerWindow(title, this, clientReplyPort, looperPort, token, bitmap); - } + } else + status = B_ERROR; } else { window = new (nothrow) ServerWindow(title, this, clientReplyPort, looperPort, token); STRACE(("\nServerApp %s: New Window %s (%g:%g, %g:%g)\n", diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp index c99a5ddf93..e0510f7be4 100644 --- a/src/servers/app/ServerFont.cpp +++ b/src/servers/app/ServerFont.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007, Haiku. + * Copyright 2001-2008, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -496,28 +496,36 @@ ServerFont::GetEdges(const char* string, int32 numBytes, class BPointEscapementConsumer { - public: - BPointEscapementConsumer(BPoint* escapements, BPoint* offsets, float size) - : fEscapements(escapements) - , fOffsets(offsets) - , fSize(size) +public: + BPointEscapementConsumer(BPoint* escapements, BPoint* offsets, + int32 numChars, float size) + : + fEscapements(escapements), + fOffsets(offsets), + fNumChars(numChars), + fSize(size) { } + void Start() {} void Finish(double x, double y) {} void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y) { _Set(index, 0, 0); } + bool ConsumeGlyph(int32 index, uint32 charCode, const GlyphCache* glyph, FontCacheEntry* entry, double x, double y) { - _Set(index, glyph->advance_x, glyph->advance_y); - return true; + return _Set(index, glyph->advance_x, glyph->advance_y); } - private: - inline void _Set(int32 index, double x, double y) + +private: + inline bool _Set(int32 index, double x, double y) { + if (index >= fNumChars) + return false; + fEscapements[index].x = x / fSize; fEscapements[index].y = y / fSize; if (fOffsets) { @@ -529,16 +537,18 @@ class BPointEscapementConsumer { fOffsets[index].x = 0; fOffsets[index].y = 0; } + return true; } BPoint* fEscapements; BPoint* fOffsets; + int32 fNumChars; float fSize; }; status_t -ServerFont::GetEscapements(const char* string, int32 numBytes, +ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars, escapement_delta delta, BPoint escapementArray[], BPoint offsetArray[]) const { @@ -547,7 +557,8 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, bool kerning = true; // TODO make this a property? - BPointEscapementConsumer consumer(escapementArray, offsetArray, fSize); + BPointEscapementConsumer consumer(escapementArray, offsetArray, numChars, + fSize); if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, &delta, kerning, fSpacing)) return B_OK; @@ -557,34 +568,42 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, class WidthEscapementConsumer { - public: - WidthEscapementConsumer(float* widths, float size) - : fWidths(widths) - , fSize(size) +public: + WidthEscapementConsumer(float* widths, int32 numChars, float size) + : + fWidths(widths), + fNumChars(numChars), + fSize(size) { } + void Start() {} void Finish(double x, double y) {} void ConsumeEmptyGlyph(int32 index, uint32 charCode, double x, double y) { fWidths[index] = 0.0; } + bool ConsumeGlyph(int32 index, uint32 charCode, const GlyphCache* glyph, FontCacheEntry* entry, double x, double y) { + if (index >= fNumChars) + return false; + fWidths[index] = glyph->advance_x / fSize; return true; } private: float* fWidths; + int32 fNumChars; float fSize; }; status_t -ServerFont::GetEscapements(const char* string, int32 numBytes, +ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars, escapement_delta delta, float widthArray[]) const { if (!string || numBytes <= 0 || !widthArray) @@ -592,7 +611,7 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, bool kerning = true; // TODO make this a property? - WidthEscapementConsumer consumer(widthArray, fSize); + WidthEscapementConsumer consumer(widthArray, numChars, fSize); if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, &delta, kerning, fSpacing)) return B_OK; @@ -813,7 +832,8 @@ ServerFont::TruncateString(BString* inOut, uint32 mode, float width) const // get the escapement of each glyph in font units float *escapementArray = new float[numChars]; static escapement_delta delta = (escapement_delta){ 0.0, 0.0 }; - if (GetEscapements(string, length, delta, escapementArray) == B_OK) { + if (GetEscapements(string, length, numChars, delta, escapementArray) + == B_OK) { truncate_string(string, mode, width, result, escapementArray, fSize, ellipsisWidth, length, numChars); diff --git a/src/servers/app/ServerFont.h b/src/servers/app/ServerFont.h index 13918dacb9..ae028c862c 100644 --- a/src/servers/app/ServerFont.h +++ b/src/servers/app/ServerFont.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007, Haiku. + * Copyright 2001-2008, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -125,12 +125,14 @@ class ServerFont { edge_info edgeArray[]) const; status_t GetEscapements(const char charArray[], - int32 numBytes, escapement_delta delta, + int32 numBytes, int32 numChars, + escapement_delta delta, BPoint escapementArray[], BPoint offsetArray[]) const; status_t GetEscapements(const char charArray[], - int32 numBytes, escapement_delta delta, + int32 numBytes, int32 numChars, + escapement_delta delta, float widthArray[]) const; status_t GetBoundingBoxes(const char charArray[],