[Scummvm-cvs-logs] SF.net SVN: scummvm:[52176] scummvm/trunk/engines/sci/engine/kpathing.cpp
thebluegr at users.sourceforge.net
thebluegr at users.sourceforge.net
Wed Aug 18 01:55:07 CEST 2010
Revision: 52176
http://scummvm.svn.sourceforge.net/scummvm/?rev=52176&view=rev
Author: thebluegr
Date: 2010-08-17 23:55:07 +0000 (Tue, 17 Aug 2010)
Log Message:
-----------
SCI: Refactored readPoint() to accept a segment reference to the polygon data, thus removing the check for invalid segment types. Also, added a sanity check to verify that the memory reference to polygon data is big enough to hold all the expected polygon vertices (thanks to waltervn)
Modified Paths:
--------------
scummvm/trunk/engines/sci/engine/kpathing.cpp
Modified: scummvm/trunk/engines/sci/engine/kpathing.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kpathing.cpp 2010-08-17 23:11:30 UTC (rev 52175)
+++ scummvm/trunk/engines/sci/engine/kpathing.cpp 2010-08-17 23:55:07 UTC (rev 52176)
@@ -261,13 +261,7 @@
int findNearPoint(const Common::Point &p, Polygon *polygon, Common::Point *ret);
};
-
-static Common::Point read_point(SegManager *segMan, reg_t list, int offset) {
- SegmentRef list_r = segMan->dereference(list);
- if (!list_r.isValid() || list_r.skipByte) {
- // If this happens, then the code below will probably go OOB and crash
- error("read_point(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(list));
- }
+static Common::Point readPoint(SegmentRef list_r, int offset) {
Common::Point point;
if (list_r.isRaw) {
@@ -350,10 +344,16 @@
Common::Point first, prev;
int i;
- prev = first = read_point(segMan, points, 0);
+ SegmentRef pointList = segMan->dereference(points);
+ if (!pointList.isValid() || pointList.skipByte) {
+ warning("draw_polygon: Polygon data pointer is invalid, skipping polygon");
+ return;
+ }
+ prev = first = readPoint(pointList, 0);
+
for (i = 1; i < size; i++) {
- Common::Point point = read_point(segMan, points, i);
+ Common::Point point = readPoint(pointList, i);
draw_line(s, prev, point, type, width, height);
prev = point;
}
@@ -401,12 +401,18 @@
debugN(-1, "%i:", type);
+ SegmentRef pointList = segMan->dereference(points);
+ if (!pointList.isValid() || pointList.skipByte) {
+ warning("print_polygon: Polygon data pointer is invalid, skipping polygon");
+ return;
+ }
+
for (i = 0; i < size; i++) {
- point = read_point(segMan, points, i);
+ point = readPoint(pointList, i);
debugN(-1, " (%i, %i)", point.x, point.y);
}
- point = read_point(segMan, points, 0);
+ point = readPoint(pointList, 0);
debug(" (%i, %i);", point.x, point.y);
}
@@ -1094,26 +1100,37 @@
Polygon *poly = new Polygon(readSelectorValue(segMan, polygon, SELECTOR(type)));
+ SegmentRef pointList = segMan->dereference(points);
+ // Check if the target polygon is still valid. It may have been released
+ // in the meantime (e.g. in LSL6, room 700, when using the elevator).
+ // Refer to bug #3034501.
+ if (!pointList.isValid() || pointList.skipByte) {
+ warning("convert_polygon: Polygon data pointer is invalid, skipping polygon");
+ return NULL;
+ }
+
+ // Make sure that we have enough points
+ if (pointList.maxSize < size * POLY_POINT_SIZE) {
+ warning("convert_polygon: Not enough memory allocated for polygon points. "
+ "Expected %d, got %d. Skipping polygon",
+ size * POLY_POINT_SIZE, pointList.maxSize);
+ return NULL;
+ }
+
int skip = 0;
// WORKAROUND: broken polygon in lsl1sci, room 350, after opening elevator
// Polygon has 17 points but size is set to 19
if ((size == 19) && g_sci->getGameId() == GID_LSL1) {
if ((s->currentRoomNumber() == 350)
- && (read_point(segMan, points, 18) == Common::Point(108, 137))) {
+ && (readPoint(pointList, 18) == Common::Point(108, 137))) {
debug(1, "Applying fix for broken polygon in lsl1sci, room 350");
size = 17;
}
}
- // Check if the target polygon is still valid. It may have been released
- // in the meantime (e.g. in LSL6, room 700, when using the elevator).
- // Refer to bug #3034501.
- if (segMan->getSegmentType(points.segment) == SEG_TYPE_INVALID)
- return NULL;
-
for (i = skip; i < size; i++) {
- Vertex *vertex = new Vertex(read_point(segMan, points, i));
+ Vertex *vertex = new Vertex(readPoint(pointList, i));
poly->vertices.insertHead(vertex);
}
@@ -1408,8 +1425,15 @@
if (DebugMan.isDebugChannelEnabled(kDebugLevelAvoidPath)) {
debug("\nReturning path:");
+
+ SegmentRef outputList = s->_segMan->dereference(output);
+ if (!outputList.isValid() || outputList.skipByte) {
+ warning("output_path: Polygon data pointer is invalid, skipping polygon");
+ return output;
+ }
+
for (int i = 0; i < offset; i++) {
- Common::Point pt = read_point(s->_segMan, output, i);
+ Common::Point pt = readPoint(outputList, i);
debugN(-1, " (%i, %i)", pt.x, pt.y);
}
debug(";\n");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list