On Tue, Jan 08, 2008 at 05:42:31PM +0100, Jiri Moskovcak wrote:
> Hi,
> I'm maintainer of Lynx package for Fedora and I found a bug in 
> implementation of StrAllocVsprintf() - it seems that it can't handle 
> formatting string like %2$s and it crashes with this message:
> *** invalid %N$ use detected *** I can fix the crash, but real fix will 
> probably require to rewrite bigger part of that function. So I'd like to 
> ask if someone can take a look at it.

Attaching the change I just checked-in (will be in dev.8)


-- 
Thomas E. Dickey <[EMAIL PROTECTED]>
http://invisible-island.net
ftp://invisible-island.net
===================================================================
RCS file: WWW/Library/Implementation/RCS/HTString.c,v
retrieving revision 1.49
diff -u -r1.49 WWW/Library/Implementation/HTString.c
--- WWW/Library/Implementation/HTString.c       2007/05/16 21:44:23     1.49
+++ WWW/Library/Implementation/HTString.c       2008/01/09 00:06:06
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTString.c,v 1.49 2007/05/16 21:44:23 tom Exp $
+ * $LynxId: HTString.c,v 1.50 2008/01/09 00:06:06 tom Exp $
  *
  *     Case-independent string comparison              HTString.c
  *
@@ -619,6 +619,46 @@
                                            const char *fmt,
                                            va_list * ap)
 {
+#ifdef HAVE_VASPRINTF
+    /*
+     * Use vasprintf() if we have it, since it is simplest.
+     */
+    char *result = 0;
+    char *temp = 0;
+
+    /* discard old destination if no length was given */
+    if (pstr && !dst_len) {
+       if (*pstr)
+           FREE(*pstr);
+    }
+
+    if (vasprintf(&temp, fmt, *ap) >= 0) {
+       if (dst_len != 0) {
+           int src_len = strlen(temp);
+           int new_len = dst_len + src_len + 1;
+
+           result = HTAlloc(pstr ? *pstr : 0, new_len);
+           if (result != 0) {
+               strcpy(result + dst_len, temp);
+               mark_malloced(temp, new_len);
+           }
+           free(temp);
+       } else {
+           result = temp;
+           mark_malloced(temp, strlen(temp));
+       }
+    }
+
+    if (pstr != 0)
+       *pstr = result;
+
+    return result;
+#else /* !HAVE_VASPRINTF */
+    /*
+     * If vasprintf() is not available, this works - but does not implement
+     * the POSIX '$' formatting character which may be used in some of the
+     * ".po" files.
+     */
 #ifdef SAVE_TIME_NOT_SPACE
     static size_t tmp_len = 0;
     static size_t fmt_len = 0;
@@ -634,20 +674,9 @@
     char *dst_ptr = *pstr;
     const char *format = fmt;
 
-    if (fmt == 0 || *fmt == '\0')
+    if (isEmpty(fmt))
        return 0;
 
-#ifdef USE_VASPRINTF
-    if (pstr && !dst_len) {
-       if (*pstr)
-           FREE(*pstr);
-       if (vasprintf(pstr, fmt, *ap) >= 0) {
-           mark_malloced(*pstr, strlen(*pstr) + 1);
-           return (*pstr);
-       }
-    }
-#endif /* USE_VASPRINTF */
-
     need = strlen(fmt) + 1;
 #ifdef SAVE_TIME_NOT_SPACE
     if (!fmt_ptr || fmt_len < need * NUM_WIDTH) {
@@ -848,6 +877,7 @@
     if (pstr)
        *pstr = dst_ptr;
     return (dst_ptr);
+#endif /* HAVE_VASPRINTF */
 }
 #undef SAVE_TIME_NOT_SPACE
 
@@ -895,16 +925,7 @@
 
     LYva_start(ap, fmt);
     {
-#ifdef USE_VASPRINTF
-       if (pstr) {
-           if (*pstr)
-               FREE(*pstr);
-           if (vasprintf(pstr, fmt, ap) >= 0)  /* else call outofmem?? */
-               mark_malloced(*pstr, strlen(*pstr) + 1);
-           result = *pstr;
-       } else
-#endif /* USE_VASPRINTF */
-           result = StrAllocVsprintf(pstr, 0, fmt, &ap);
+       result = StrAllocVsprintf(pstr, 0, fmt, &ap);
     }
     va_end(ap);
 
_______________________________________________
Lynx-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lynx-dev

Reply via email to