diff --git a/src/kits/interface/PicturePlayer.cpp b/src/kits/interface/PicturePlayer.cpp index e59243a213..7d85d521ec 100644 --- a/src/kits/interface/PicturePlayer.cpp +++ b/src/kits/interface/PicturePlayer.cpp @@ -58,9 +58,14 @@ PicturePlayer::~PicturePlayer() status_t PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) { - // TODO: we should probably check if the functions in the table are not NULL - // before calling them. + // We don't check if the functions in the table are NULL, but we + // check the tableEntries to see if the table is big enough. + // If an application supplies the wrong size or an invalid pointer, + // it's its own fault. + // TODO: Call the exit_font_state_change and exit_state_change hooks. + // there are no ops for them, so we need to keep track of the size of the data block, + // and call them when we are at the end. const char *data = reinterpret_cast(fData); size_t pos = 0; @@ -76,6 +81,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) switch (op) { case B_PIC_MOVE_PEN_BY: { + if (tableEntries <= 1) + break; ((fnc_BPoint)callBackTable[1])(userData, *reinterpret_cast(data)); /* where */ break; @@ -83,6 +90,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_STROKE_LINE: { + if (tableEntries <= 2) + break; ((fnc_BPointBPoint)callBackTable[2])(userData, *reinterpret_cast(data), /* start */ *reinterpret_cast(data + sizeof(BPoint))); /* end */ @@ -91,6 +100,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_STROKE_RECT: { + if (tableEntries <= 3) + break; ((fnc_BRect)callBackTable[3])(userData, *reinterpret_cast(data)); /* rect */ break; @@ -98,6 +109,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_FILL_RECT: { + if (tableEntries <= 4) + break; ((fnc_BRect)callBackTable[4])(userData, *reinterpret_cast(data)); /* rect */ break; @@ -105,6 +118,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_STROKE_ROUND_RECT: { + if (tableEntries <= 5) + break; ((fnc_BRectBPoint)callBackTable[5])(userData, *reinterpret_cast(data), /* rect */ *reinterpret_cast(data + sizeof(BRect))); /* radii */ @@ -113,6 +128,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_FILL_ROUND_RECT: { + if (tableEntries <= 6) + break; ((fnc_BRectBPoint)callBackTable[6])(userData, *reinterpret_cast(data), /* rect */ *reinterpret_cast(data + sizeof(BRect))); /* radii */ @@ -121,6 +138,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_STROKE_BEZIER: { + if (tableEntries <= 7) + break; ((fnc_PBPoint)callBackTable[7])(userData, reinterpret_cast(data)); break; @@ -128,6 +147,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_FILL_BEZIER: { + if (tableEntries <= 8) + break; ((fnc_PBPoint)callBackTable[8])(userData, reinterpret_cast(data)); break; @@ -135,6 +156,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_STROKE_ARC: { + if (tableEntries <= 9) + break; ((fnc_BPointBPointff)callBackTable[9])(userData, *reinterpret_cast(data), /* center */ *reinterpret_cast(data + sizeof(BPoint)), /* radii */ @@ -145,6 +168,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_FILL_ARC: { + if (tableEntries <= 10) + break; ((fnc_BPointBPointff)callBackTable[10])(userData, *reinterpret_cast(data), /* center */ *reinterpret_cast(data + sizeof(BPoint)), /* radii */ @@ -155,6 +180,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_STROKE_ELLIPSE: { + if (tableEntries <= 11) + break; const BRect *rect = reinterpret_cast(data); BPoint radii((rect->Width() + 1) / 2.0f, (rect->Height() + 1) / 2.0f); BPoint center = rect->LeftTop() + radii; @@ -164,6 +191,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_FILL_ELLIPSE: { + if (tableEntries <= 12) + break; const BRect *rect = reinterpret_cast(data); BPoint radii((rect->Width() + 1) / 2.0f, (rect->Height() + 1) / 2.0f); BPoint center = rect->LeftTop() + radii; @@ -173,6 +202,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_STROKE_POLYGON: { + if (tableEntries <= 13) + break; int32 numPoints = *reinterpret_cast(data); ((fnc_iPBPointb)callBackTable[13])(userData, numPoints, @@ -183,6 +214,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_FILL_POLYGON: { + if (tableEntries <= 14) + break; ((fnc_iPBPoint)callBackTable[14])(userData, *reinterpret_cast(data), /* numPoints */ reinterpret_cast(data + sizeof(int32))); /* points */ @@ -192,6 +225,10 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_STROKE_SHAPE: case B_PIC_FILL_SHAPE: { + const bool stroke = (op == B_PIC_STROKE_SHAPE); + if (tableEntries <= 16 || (stroke && tableEntries <= 15)) + break; + int32 opCount = *reinterpret_cast(data); int32 ptCount = *reinterpret_cast(data + sizeof(int32)); const uint32 *opList = reinterpret_cast(data + 2 * sizeof(int32)); @@ -201,13 +238,15 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) BShape shape; shape.SetData(opCount, ptCount, opList, ptList); - const int32 tableIndex = (op == B_PIC_STROKE_SHAPE) ? 15 : 16; + const int32 tableIndex = stroke ? 15 : 16; ((fnc_BShape)callBackTable[tableIndex])(userData, &shape); break; } case B_PIC_DRAW_STRING: { + if (tableEntries <= 17) + break; ((fnc_Pcff)callBackTable[17])(userData, reinterpret_cast(data + 2 * sizeof(float)), /* string */ *reinterpret_cast(data), /* escapement.space */ @@ -217,6 +256,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_DRAW_PIXELS: { + if (tableEntries <= 18) + break; ((fnc_DrawPixels)callBackTable[18])(userData, *reinterpret_cast(data), /* src */ *reinterpret_cast(data + 1 * sizeof(BRect)), /* dst */ @@ -231,6 +272,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_DRAW_PICTURE: { + if (tableEntries <= 19) + break; ((fnc_DrawPicture)callBackTable[19])(userData, *reinterpret_cast(data), *reinterpret_cast(data + sizeof(BPoint))); @@ -239,46 +282,62 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_CLIPPING_RECTS: { + if (tableEntries <= 20) + break; break; } case B_PIC_CLEAR_CLIPPING_RECTS: { + if (tableEntries <= 20) + break; ((fnc_PBRecti)callBackTable[20])(userData, NULL, 0); break; } case B_PIC_CLIP_TO_PICTURE: { + if (tableEntries <= 21) + break; break; } case B_PIC_PUSH_STATE: { + if (tableEntries <= 22) + break; ((fnc)callBackTable[22])(userData); break; } case B_PIC_POP_STATE: { + if (tableEntries <= 23) + break; ((fnc)callBackTable[23])(userData); break; } case B_PIC_ENTER_STATE_CHANGE: { + if (tableEntries <= 24) + break; ((fnc)callBackTable[24])(userData); break; } case B_PIC_ENTER_FONT_STATE: { + if (tableEntries <= 26) + break; ((fnc)callBackTable[26])(userData); break; } case B_PIC_SET_ORIGIN: { + if (tableEntries <= 28) + break; ((fnc_BPoint)callBackTable[28])(userData, *reinterpret_cast(data)); /* origin */ break; @@ -286,6 +345,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_PEN_LOCATION: { + if (tableEntries <= 29) + break; ((fnc_BPoint)callBackTable[29])(userData, *reinterpret_cast(data)); /* location */ break; @@ -293,6 +354,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_DRAWING_MODE: { + if (tableEntries <= 30) + break; ((fnc_s)callBackTable[30])(userData, *reinterpret_cast(data)); /* mode */ break; @@ -300,6 +363,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_LINE_MODE: { + if (tableEntries <= 31) + break; ((fnc_ssf)callBackTable[31])(userData, *reinterpret_cast(data), /* cap-mode */ *reinterpret_cast(data + 1 * sizeof(int16)), /* join-mode */ @@ -309,6 +374,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_PEN_SIZE: { + if (tableEntries <= 32) + break; ((fnc_f)callBackTable[32])(userData, *reinterpret_cast(data)); /* size */ break; @@ -316,13 +383,17 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FORE_COLOR: { + if (tableEntries <= 33) + break; ((fnc_Color)callBackTable[33])(userData, *reinterpret_cast(data)); /* color */ break; } case B_PIC_SET_BACK_COLOR: - { + { + if (tableEntries <= 34) + break; ((fnc_Color)callBackTable[34])(userData, *reinterpret_cast(data)); /* color */ break; @@ -330,6 +401,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_STIPLE_PATTERN: { + if (tableEntries <= 35) + break; ((fnc_Pattern)callBackTable[35])(userData, *reinterpret_cast(data)); /* pattern */ break; @@ -337,6 +410,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_SCALE: { + if (tableEntries <= 36) + break; ((fnc_f)callBackTable[36])(userData, *reinterpret_cast(data)); /* scale */ break; @@ -344,7 +419,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_FAMILY: { - debugger("B_PIC_SET_FONT_FAMILY"); // TODO: is this unused? + if (tableEntries <= 37) + break; ((fnc_Pc)callBackTable[37])(userData, reinterpret_cast(data)); /* string */ break; @@ -352,7 +428,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_STYLE: { - debugger("B_PIC_SET_FONT_STYLE"); // TODO: is this unused? + if (tableEntries <= 38) + break; ((fnc_Pc)callBackTable[38])(userData, reinterpret_cast(data)); /* string */ break; @@ -360,6 +437,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_SPACING: { + if (tableEntries <= 39) + break; ((fnc_i)callBackTable[39])(userData, *reinterpret_cast(data)); /* spacing */ break; @@ -367,6 +446,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_SIZE: { + if (tableEntries <= 40) + break; ((fnc_f)callBackTable[40])(userData, *reinterpret_cast(data)); /* size */ break; @@ -374,6 +455,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_ROTATE: { + if (tableEntries <= 41) + break; ((fnc_f)callBackTable[41])(userData, *reinterpret_cast(data)); /* rotation */ break; @@ -381,6 +464,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_ENCODING: { + if (tableEntries <= 42) + break; ((fnc_i)callBackTable[42])(userData, *reinterpret_cast(data)); /* encoding */ break; @@ -388,6 +473,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_FLAGS: { + if (tableEntries <= 43) + break; ((fnc_i)callBackTable[43])(userData, *reinterpret_cast(data)); /* flags */ break; @@ -395,6 +482,8 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_SHEAR: { + if (tableEntries <= 44) + break; ((fnc_f)callBackTable[44])(userData, *reinterpret_cast(data)); /* shear */ break; @@ -402,16 +491,17 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData) case B_PIC_SET_FONT_FACE: { + if (tableEntries <= 46) + break; ((fnc_i)callBackTable[46])(userData, *reinterpret_cast(data)); /* flags */ break; } - // TODO: Looks like R5 function table only exports 47 functions... - // I added this here as a temporary workaround, because there seems to be - // no room for this op, although it's obviously implemented in some way... case B_PIC_SET_BLENDING_MODE: { + if (tableEntries <= 47) + break; ((fnc_ss)callBackTable[47])(userData, *reinterpret_cast(data), /* alphaSrcMode */ *reinterpret_cast(data + sizeof(int16))); /* alphaFncMode */ diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 23b9839b7b..ec8da21d69 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -595,7 +595,10 @@ set_font_style(ViewLayer *view, const char *style) static void set_font_spacing(ViewLayer *view, int32 spacing) { - printf("SetFontSpacing(%ld)\n", spacing); + ServerFont font; + font.SetSpacing(spacing); + view->CurrentState()->SetFont(font, B_FONT_SPACING); + view->Window()->GetDrawingEngine()->SetFont(view->CurrentState()->Font()); } @@ -622,28 +625,40 @@ set_font_rotate(ViewLayer *view, float rotation) static void set_font_encoding(ViewLayer *view, int32 encoding) { - printf("SetFontEncoding(%ld)\n", encoding); + ServerFont font; + font.SetEncoding(encoding); + view->CurrentState()->SetFont(font, B_FONT_ENCODING); + view->Window()->GetDrawingEngine()->SetFont(view->CurrentState()->Font()); } static void set_font_flags(ViewLayer *view, int32 flags) { - printf("SetFontFlags(%ld)\n", flags); + ServerFont font; + font.SetFlags(flags); + view->CurrentState()->SetFont(font, B_FONT_FLAGS); + view->Window()->GetDrawingEngine()->SetFont(view->CurrentState()->Font()); } static void set_font_shear(ViewLayer *view, float shear) { - printf("SetFontShear(%.2f)\n", shear); + ServerFont font; + font.SetShear(shear); + view->CurrentState()->SetFont(font, B_FONT_SHEAR); + view->Window()->GetDrawingEngine()->SetFont(view->CurrentState()->Font()); } static void -set_font_face(ViewLayer *view, int32 flags) +set_font_face(ViewLayer *view, int32 face) { - printf("SetFontFace(%ld)\n", flags); + ServerFont font; + font.SetFace(face); + view->CurrentState()->SetFont(font, B_FONT_FACE); + view->Window()->GetDrawingEngine()->SetFont(view->CurrentState()->Font()); } @@ -707,7 +722,7 @@ const void *tableEntries[] = { (const void *)set_font_flags, (const void *)set_font_shear, (const void *)reserved, // TODO: Marc Flerackers calls this "set_font_bpp". Investigate - (const void *)set_font_face, // TODO: R5 function table ends here... how is set blending mode implemented there ? + (const void *)set_font_face, (const void *)set_blending_mode };