From 6e0ed3c1c63dad639cd0820870eb98680d05071c Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Sat, 26 Mar 2005 04:42:28 +0000
Subject: [PATCH] add various portability and potential segfault fixes
 involving getcwd() calls

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2428 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog   | 15 +++++++++++++++
 src/files.c | 52 ++++++++++++++++++++++------------------------------
 src/nano.h  |  2 +-
 src/utils.c |  1 +
 4 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 68933b3b..943fc55a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,8 +12,18 @@ CVS code -
   cut_to_eol()
 	- Fix inaccurate comment. (DLR)
 - files.c:
+  get_full_path()
+	- Rework handling of the results of getcwd() in order to avoid
+	  segfaults if they fail, and to remove uses of the nonportable
+	  GNU extension where passing a size of 0 will get a string as
+	  long as we need. (DLR)
   do_browser()
 	- Rename variable lineno to fileline to avoid confusion. (DLR)
+  do_browse_from()
+	- Rework handling of the results of getcwd() in order to avoid
+	  segfaults if they fail, and to remove uses of the nonportable
+	  GNU extension where passing a size of 0 will get a string as
+	  long as we need. (DLR)
 - nano.c:
   help_init()
 	- When calculating allocsize, take multibyte characters into
@@ -39,6 +49,11 @@ CVS code -
 	- Instead of breaking a line at a space and readding the space
 	  afterwards, just break the line after the space, as it's more
 	  efficient. (DLR)
+- nano.h:
+	- Define PATH_MAX as 4096 if it isn't defined, as passing a size
+	  of 0 to get a string as long as we need is a nonportable GNU
+	  extension, and hence it won't work on non-GNU systems that
+	  don't define PATH_MAX. (DLR)
 - utils.c:
   regexec_safe()
 	- Rename to safe_regexec() for consistency. (DLR)
diff --git a/src/files.c b/src/files.c
index 7be70ec9..ff2ade33 100644
--- a/src/files.c
+++ b/src/files.c
@@ -983,15 +983,8 @@ char *get_full_path(const char *origpath)
     	return NULL;
 
     /* Get the current directory. */
-#if PATH_MAX != -1
     d_here = charalloc(PATH_MAX + 1);
-#else
-    d_here = NULL;
-#endif
     d_here = getcwd(d_here, PATH_MAX + 1);
-#if PATH_MAX != -1
-    align(&d_here);
-#endif
 
     if (d_here != NULL) {
 	const char *last_slash;
@@ -999,6 +992,8 @@ char *get_full_path(const char *origpath)
 	bool path_only;
 	struct stat fileinfo;
 
+	align(&d_here);
+
 	/* If the current directory isn't "/", tack a slash onto the end
 	 * of it. */
 	if (strcmp(d_here, "/") != 0) {
@@ -1055,26 +1050,24 @@ char *get_full_path(const char *origpath)
 	    } else {
 		/* Get the full path and save it in d_there. */
 		free(d_there);
-#if PATH_MAX != -1
+
 		d_there = charalloc(PATH_MAX + 1);
-#else
-		d_there = NULL;
-#endif
 		d_there = getcwd(d_there, PATH_MAX + 1);
-#if PATH_MAX != -1
-		align(&d_there);
-#endif
 
-		if (d_there == NULL)
+		if (d_there != NULL) {
+		    align(&d_there);
+
+		    if (strcmp(d_there, "/") != 0) {
+			/* Make sure d_there ends in a slash. */
+			d_there = charealloc(d_there,
+				strlen(d_there) + 2);
+			strcat(d_there, "/");
+		    }
+		} else
 		    /* If we couldn't get the full path, set path_only
 		     * to TRUE so that we clean up correctly, free all
 		     * allocated memory, and return NULL. */
 		    path_only = TRUE;
-		else if (strcmp(d_there, "/") != 0) {
-		    /* Make sure d_there ends in a slash. */
-		    d_there = charealloc(d_there, strlen(d_there) + 2);
-		    strcat(d_there, "/");
-		}
 
 		/* Finally, go back to the path specified in d_here,
 		 * where we were before. */
@@ -1090,7 +1083,7 @@ char *get_full_path(const char *origpath)
 	 * d_there_file contains the filename portion of the answer.  If
 	 * this is the case, tack d_there_file onto the end of
 	 * d_there, so that d_there contains the complete answer. */
-	if (!path_only && d_there) {
+	if (!path_only && d_there != NULL) {
 	    d_there = charealloc(d_there, strlen(d_there) +
 		strlen(d_there_file) + 1);
 	    strcat(d_there, d_there_file);
@@ -2764,7 +2757,7 @@ char *do_browse_from(const char *inpath)
     struct stat st;
     char *path;
 	/* This holds the tilde-expanded version of inpath. */
-    DIR *dir;
+    DIR *dir = NULL;
 
     assert(inpath != NULL);
 
@@ -2780,15 +2773,12 @@ char *do_browse_from(const char *inpath)
 	striponedir(path);
 	if (stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
 	    free(path);
-#if PATH_MAX != -1
+
 	    path = charalloc(PATH_MAX + 1);
-#else
-	    path = NULL;
-#endif
 	    path = getcwd(path, PATH_MAX + 1);
-#if PATH_MAX != -1
-	    align(&path);
-#endif
+
+	    if (path != NULL)
+		align(&path);
 	}
     }
 
@@ -2802,7 +2792,9 @@ char *do_browse_from(const char *inpath)
     }
 #endif
 
-    dir = opendir(path);
+    if (path != NULL)
+	dir = opendir(path);
+
     if (dir == NULL) {
 	beep();
 	free(path);
diff --git a/src/nano.h b/src/nano.h
index 28d5249a..5fc3d616 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -55,7 +55,7 @@
 /* Set a default value for PATH_MAX, so we can use it in lines like
  * "path = getcwd(NULL, PATH_MAX + 1);". */
 #ifndef PATH_MAX
-#define PATH_MAX -1
+#define PATH_MAX 4096
 #endif
 
 #ifdef USE_SLANG
diff --git a/src/utils.c b/src/utils.c
index ce21eced..af0055ea 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -110,6 +110,7 @@ bool parse_num(const char *str, ssize_t *val)
 void align(char **strp)
 {
     assert(strp != NULL);
+
     if (*strp != NULL)
 	*strp = charealloc(*strp, strlen(*strp) + 1);
 }
-- 
GitLab