* Do not trust the client! ServerFont::GetEscapements() now takes a
parameter for the length of the arrays, so that even if the char/byte counts do not match, no memory is overwritten anymore. This fixes bug #1862; .canna obviously contains invalid UTF-8 characters, or there is a bug in StyledEdit (or deeper) and it doesn't call BFont::GetEscapements() correctly. * Fixed some cases of unchecked allocations in the font handling methods of ServerApp, added TODOs to all other ones. * Improved error code when creating a window fails. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24160 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e705558bb9
commit
a4de7fa0fa
@ -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<int32>(&numChars);
|
||||
link.Read<int32>(&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<int32>(&numChars);
|
||||
link.Read<int32>(&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<uint32>(&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<uint32>(&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<BPoint>(escapements[i]);
|
||||
|
||||
if (wantsOffsets) {
|
||||
if (offsets) {
|
||||
for (int32 i = 0; i < numChars; i++)
|
||||
fLink.Attach<BPoint>(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<uint32>(&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<uint32>(&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",
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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[],
|
||||
|
Loading…
Reference in New Issue
Block a user