Fix crashes when some external APIs fail

Hi,

I’m a PhD student. I analyzed the BK source code and found some potential API bugs that may cause crashes.

These crashes are mainly caused by insufficient error handling of API functions like chdir, gethostbyname or XGetImage.

I think it’s unsafe to assume the library function would be correct. It would be better if we could handle the error properly.

I can’t upload the patch so far, so I post the patch (against version 7.3.2) here.

Best,
Zhouyang

diff --git a/src/gui/tcltk/tk/generic/tkCanvPs.c b/src/gui/tcltk/tk/generic/tkCanvPs.c
index c6470dd..f39838e 100644
--- a/src/gui/tcltk/tk/generic/tkCanvPs.c
+++ b/src/gui/tcltk/tk/generic/tkCanvPs.c
@@ -903,6 +903,10 @@ PostscriptBitmap(
 	    (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
     imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0,
 	    totalWidth, totalHeight, 1, XYPixmap);
+    if (imagePtr == NULL) {
+        fprintf(stderr, "Failed to get the X image!\n");
+        return;
+    }
 
     Tcl_AppendToObj(psObj, "<", -1);
     mask = 0x80;
diff --git a/src/libc/utils/fullname.c b/src/libc/utils/fullname.c
index afdfe30..7a5b870 100644
--- a/src/libc/utils/fullname.c
+++ b/src/libc/utils/fullname.c
@@ -120,7 +120,12 @@ fullLink(char *xfile, char *tmp, int followLink)
 	}
 
 	cleanPath(tmp, tmp);
-	if (here[0]) chdir(here);
+	if (here[0]) { 
+		if (chdir(here)) {
+			perror("chdir error");
+			exit(1);
+		}
+	}
 	if (tmp == buf) tmp = strdup(buf);
 	return (tmp);
 }
diff --git a/src/port/ns_sock_host2ip.c b/src/port/ns_sock_host2ip.c
index a3adf81..066dc0e 100644
--- a/src/port/ns_sock_host2ip.c
+++ b/src/port/ns_sock_host2ip.c
@@ -30,7 +30,8 @@ ns_sock_host2ip(char *host, int trace)
 
 	p = getenv("SOCKS_NS");
 	if (p && *p) {
-		gethostbyname("localhost"); /* force init the res structure */
+		if (gethostbyname("localhost") == NULL) /* force init the res structure */
+			perror("fail to get localhost");
 		res_init();
 		/* save the original values */
 		nsaddr_sav = _res.nsaddr_list[0].sin_addr.s_addr;

Sorry you didn’t get a reply earlier.

I don’t really have a good path to accept csets for BitKeeper unless you want to host it somewhere where I can pull your changes. But I can import this patch in your name. Send me the email address I should use.

I won’t take the change in Tcl/Tk since L tries to track the original Tcl/TK source as close as possible, bugs and all.

The other two changes look fine, but I assume you noticed that they are just a couple of many many you would find when looking for these sorts of changes. And then if you go and try to fix all of them it will inevitably cause bugs and reduce the stability of the code. I speak from experience in this.

Pushed these fixes to bk://bkbits.net/bk/dev

http://repos.bkbits.net/bk/dev/?PAGE=patch&REV=5aaba253qRvtwKAXxkwqx2Rkqnzndw

Thanks!