Re: SIGSEGV in the inernal viewer when in hex mode



Hello!

>        I've got "Segmentation fault" when I tried to search text in quotes
> with the internal file viewer when in HEX MODE. This error has occured
> when:
> 1. You're viewing some file with the internal viewer.
> 2. You're viewing file in hex mode.
> 3. You're trying to enter search string.
> 3. You're entering quoted text in search field.
> 4. You've forgot enclosing double-quote.

Thank you!  I'm fixing this bug in CVS.  It appears that sscanf is not
quite reliable even in glibc (for this particular task).  I'm replacing it
with a simple scan for double quotes using strchr.

-----------------------------------
--- ChangeLog
+++ ChangeLog
@@ -1 +1,6 @@
+2001-09-02  Pavel Roskin  <proski gnu org>
+
+	* view.c (hex_search): Don't use sscanf() to search for quoted
+	strings - use strchr instead.
+
 2001-08-31 23:14:21  Timur Bakeyev  <mc bat ru>
--- view.c
+++ view.c
@@ -1680,9 +1680,10 @@ block_search (WView *view, char *buffer,
 static void
 hex_search (WView *view, char *text)
 {
-    char *buffer;		/* Where we hold the information */
-    long pos;			/* Where did we found the string */
-    int  block_len = 0;
+    char *buffer;		/* Parsed search string */
+    char *cur;			/* Current position in it */
+    int  block_len;		/* Length of the search string */
+    long pos;			/* Position of the string in the file */
     int  parse_error = 0;

     if (!*text) {
@@ -1692,12 +1693,19 @@ hex_search (WView *view, char *text)

     /* buffer will never be longer that text */
     buffer = g_new (char, strlen (text));
+    cur = buffer;

     /* First convert the string to a stream of bytes */
     while (*text) {
 	int val;
 	int ptr;

+	/* Skip leading spaces */
+	if (*text == ' ' || *text == '\t') {
+	    text++;
+	    continue;
+	}
+
 	/* %i matches octal, decimal, and hexadecimal numbers */
 	if (sscanf (text, "%i%n", &val, &ptr) > 0) {
 	    /* Allow signed and unsigned char in the user input */
@@ -1706,21 +1714,31 @@ hex_search (WView *view, char *text)
 		break;
 	    }

-	    buffer [block_len++] = (char) val;
+	    *cur++ = (char) val;
 	    text += ptr;
 	    continue;
 	}

 	/* Try quoted string, strip quotes */
-	if (sscanf (text, "\"%[^\"]\"%n", buffer + block_len, &ptr) > 0) {
-	    text += ptr;
-	    block_len += ptr - 2;
-	    continue;
+	if (*text == '"') {
+	    char *next_quote;
+
+	    text++;
+	    next_quote = strchr (text, '"');
+	    if (next_quote) {
+		memcpy (cur, text, next_quote - text);
+		cur += next_quote - text;
+		text = next_quote + 1;
+		continue;
+	    }
+	    /* fall through */
 	}

 	parse_error = 1;
 	break;
     }
+
+    block_len = cur - buffer;

     /* No valid bytes in the user input */
     if (block_len <= 0 || parse_error) {
-----------------------------------

> #20 0x808ec92 in vline ()
> #21 0x40139639 in __libc_start_main () from /lib/libc.so.6
> #22 0xb in ?? ()
> #23 0xbffffb14 in ?? ()
> #24 0x4e45504f in ?? ()
> Cannot access memory at address 0x5353454c.

Unfortunately, with modern gcc you only get useful backtraces from
programs compiled without optimization.

Fixed snapshot has been uploaded here: http://www.red-bean.com/~proski/mc/

-- 
Regards,
Pavel Roskin





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]