sdiff: fix wcwidth recursion
authorJohn Marino <draco@marino.st>
Wed, 12 Oct 2011 22:39:51 +0000 (00:39 +0200)
committerJohn Marino <draco@marino.st>
Thu, 13 Oct 2011 00:04:49 +0000 (02:04 +0200)
Apparently trying to diff non-UTF8 documents caused a stack overflow.
The culprit was correctly identified by Yonetani as the redefinition
of wcwidth in the wcwidth.c file.  Within that function, it calls itself
recursively forever.  I'm not sure how this would work differently
(macro or not) on another system.

My solution was to stop redefining wcwidth and just create a separate
function, one that will call the system wcwidth function as needed.

reported by: Peter Avalos
http://bugs.dragonflybsd.org/issue2134

contrib/diffutils/README.DRAGONFLY
contrib/diffutils/lib/wcwidth.c
contrib/diffutils/src/side.c
gnu/usr.bin/diff/libdiffutils/gnuwidechar.h [new file with mode: 0644]

index 854baca..609dce9 100644 (file)
@@ -12,7 +12,8 @@ sha1 = 17fcdcd435ef6b424aa9c7a487ffde408d1a00e6
 A list of files and directories removed is in README.DELETED
 
 Local modifications applied to following files:
-       diff.c
-       diff3.c
-       sdiff.c
-       
+       src/diff.c
+       src/diff3.c
+       src/sdiff.c
+       src/side.c
+       lib/wcwidth.c
index 66b5b15..54681b5 100644 (file)
@@ -18,6 +18,7 @@
 
 /* Specification.  */
 #include <wchar.h>
+#include <gnuwidechar.h>
 
 /* Get iswprint.  */
 #include <wctype.h>
@@ -27,8 +28,7 @@
 #include "uniwidth.h"
 
 int
-wcwidth (wchar_t wc)
-#undef wcwidth
+special_wcwidth (wchar_t wc)
 {
   /* In UTF-8 locales, use a Unicode aware width function.  */
   const char *encoding = locale_charset ();
index 6aa96a9..b126e9e 100644 (file)
@@ -23,6 +23,7 @@
 #include "diff.h"
 
 #include <wchar.h>
+#include <gnuwidechar.h>
 
 static void print_sdiff_common_lines (lin, lin);
 static void print_sdiff_hunk (struct change *);
@@ -138,7 +139,7 @@ print_half_line (char const *const *line, size_t indent, size_t out_bound)
 
            if (0 < bytes && bytes < (size_t) -2)
              {
-               int width = wcwidth (wc);
+               int width = special_wcwidth (wc);
                if (0 < width)
                  in_position += width;
                if (in_position <= out_bound)
diff --git a/gnu/usr.bin/diff/libdiffutils/gnuwidechar.h b/gnu/usr.bin/diff/libdiffutils/gnuwidechar.h
new file mode 100644 (file)
index 0000000..83ed5cc
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Works around wcwidth recursive problem while maintaining UTF-8
+ * handling functionality.
+ */
+
+#ifndef _GNUWIDECHAR_H_
+#define _GNUWIDECHAR_H_
+
+int special_wcwidth(wchar_t);
+
+#endif /* !_GNUWIDECHAR_H_ */