[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