* lib/count-one-bits.h: Add comments. (From Bruno Haible.)
[gnulib.git] / lib / linebreak.c
index c0ae082..73dba73 100644 (file)
@@ -1,5 +1,5 @@
 /* linebreak.c - line breaking of Unicode strings
-   Copyright (C) 2001-2003 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
 This program is free software; you can redistribute it and/or modify
@@ -13,12 +13,10 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+along with this program; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
 
 /* Specification.  */
 #include "linebreak.h"
@@ -26,14 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <stdlib.h>
 #include <string.h>
 #include "c-ctype.h"
-
-#include "utf8-ucs4.h"
-
-#include "utf16-ucs4.h"
+#include "xsize.h"
+#include "unistr.h"
 
 #ifdef unused
 static inline int
-u32_mbtouc (unsigned int *puc, const unsigned int *s, size_t n)
+u32_mbtouc_unsafe (unsigned int *puc, const unsigned int *s, size_t n)
 {
   *puc = *s;
   return 1;
@@ -473,7 +469,7 @@ u8_width (const unsigned char *s, size_t n, const char *encoding)
       unsigned int uc;
       int w;
 
-      s += u8_mbtouc (&uc, s, s_end - s);
+      s += u8_mbtouc_unsafe (&uc, s, s_end - s);
 
       if (uc == 0)
         break; /* end of string reached */
@@ -497,7 +493,7 @@ u16_width (const unsigned short *s, size_t n, const char *encoding)
       unsigned int uc;
       int w;
 
-      s += u16_mbtouc (&uc, s, s_end - s);
+      s += u16_mbtouc_unsafe (&uc, s, s_end - s);
 
       if (uc == 0)
         break; /* end of string reached */
@@ -643,7 +639,7 @@ u8_possible_linebreaks (const unsigned char *s, size_t n, const char *encoding,
   while (s < s_end)
     {
       unsigned int uc;
-      int count = u8_mbtouc (&uc, s, s_end - s);
+      int count = u8_mbtouc_unsafe (&uc, s, s_end - s);
       int prop = lbrkprop_lookup (uc);
 
       if (prop == LBP_BK)
@@ -755,7 +751,7 @@ u16_possible_linebreaks (const unsigned short *s, size_t n, const char *encoding
   while (s < s_end)
     {
       unsigned int uc;
-      int count = u16_mbtouc (&uc, s, s_end - s);
+      int count = u16_mbtouc_unsafe (&uc, s, s_end - s);
       int prop = lbrkprop_lookup (uc);
 
       if (prop == LBP_BK)
@@ -984,7 +980,7 @@ u8_width_linebreaks (const unsigned char *s, size_t n,
   while (s < s_end)
     {
       unsigned int uc;
-      int count = u8_mbtouc (&uc, s, s_end - s);
+      int count = u8_mbtouc_unsafe (&uc, s, s_end - s);
 
       /* Respect the override.  */
       if (o != NULL && *o != UC_BREAK_UNDEFINED)
@@ -1023,7 +1019,7 @@ u8_width_linebreaks (const unsigned char *s, size_t n,
               /* No line break for the moment, may be turned into
                  UC_BREAK_POSSIBLE later, via last_p. */
             }
-         
+
           *p = UC_BREAK_PROHIBITED;
 
           w = uc_width (uc, encoding);
@@ -1068,7 +1064,7 @@ u16_width_linebreaks (const unsigned short *s, size_t n,
   while (s < s_end)
     {
       unsigned int uc;
-      int count = u16_mbtouc (&uc, s, s_end - s);
+      int count = u16_mbtouc_unsafe (&uc, s, s_end - s);
 
       /* Respect the override.  */
       if (o != NULL && *o != UC_BREAK_UNDEFINED)
@@ -1107,7 +1103,7 @@ u16_width_linebreaks (const unsigned short *s, size_t n,
               /* No line break for the moment, may be turned into
                  UC_BREAK_POSSIBLE later, via last_p. */
             }
-         
+
           *p = UC_BREAK_PROHIBITED;
 
           w = uc_width (uc, encoding);
@@ -1190,7 +1186,7 @@ u32_width_linebreaks (const unsigned int *s, size_t n,
               /* No line break for the moment, may be turned into
                  UC_BREAK_POSSIBLE later, via last_p. */
             }
-         
+
           *p = UC_BREAK_PROHIBITED;
 
           w = uc_width (uc, encoding);
@@ -1383,7 +1379,7 @@ iconv_string_length (iconv_t cd, const char *s, size_t n)
         return (size_t)(-1);
       count += outptr - tmpbuf;
     }
-  /* Avoid glibc-2.1 bug and Solaris 2.7-2.9 bug.  */
+  /* Avoid glibc-2.1 bug and Solaris 7 through 9 bug.  */
 #if defined _LIBICONV_VERSION \
     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
   {
@@ -1448,7 +1444,7 @@ iconv_string_keeping_offsets (iconv_t cd, const char *s, size_t n,
       if (res == (size_t)(-1))
         abort ();
     }
-  /* Avoid glibc-2.1 bug and Solaris 2.7 bug.  */
+  /* Avoid glibc-2.1 bug and Solaris 7 bug.  */
 #if defined _LIBICONV_VERSION \
     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
   if (iconv (cd, NULL, NULL, &outptr, &outsize) == (size_t)(-1))
@@ -1498,7 +1494,7 @@ mbs_possible_linebreaks (const char *s, size_t n, const char *encoding,
        to_utf8 = (iconv_t)(-1);
       else
 # endif
-      /* Avoid Solaris 2.9 bug with GB2312, EUC-TW, BIG5, BIG5-HKSCS, GBK,
+      /* Avoid Solaris 9 bug with GB2312, EUC-TW, BIG5, BIG5-HKSCS, GBK,
          GB18030.  */
 # if defined __sun && !defined _LIBICONV_VERSION
       if (   STREQ (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0)
@@ -1519,7 +1515,9 @@ mbs_possible_linebreaks (const char *s, size_t n, const char *encoding,
             {
               /* Convert the string to UTF-8 and build a translation table
                  from offsets into s to offsets into the translated string.  */
-              char *memory = malloc (n * sizeof (size_t) + m + m);
+             size_t memory_size = xsum3 (xtimes (n, sizeof (size_t)), m, m);
+              char *memory =
+               (size_in_bounds_p (memory_size) ? malloc (memory_size) : NULL);
               if (memory != NULL)
                 {
                   size_t *offtable = (size_t *) memory;
@@ -1591,7 +1589,7 @@ mbs_width_linebreaks (const char *s, size_t n,
        to_utf8 = (iconv_t)(-1);
       else
 # endif
-      /* Avoid Solaris 2.9 bug with GB2312, EUC-TW, BIG5, BIG5-HKSCS, GBK,
+      /* Avoid Solaris 9 bug with GB2312, EUC-TW, BIG5, BIG5-HKSCS, GBK,
          GB18030.  */
 # if defined __sun && !defined _LIBICONV_VERSION
       if (   STREQ (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0)
@@ -1612,7 +1610,12 @@ mbs_width_linebreaks (const char *s, size_t n,
             {
               /* Convert the string to UTF-8 and build a translation table
                  from offsets into s to offsets into the translated string.  */
-              char *memory = malloc (n * sizeof (size_t) + m + m + (o != NULL ? m : 0));
+             size_t memory_size =
+               xsum4 (xtimes (n, sizeof (size_t)), m, m,
+                      (o != NULL ? m : 0));
+             char *memory =
+               (char *)
+               (size_in_bounds_p (memory_size) ? malloc (memory_size) : NULL);
               if (memory != NULL)
                 {
                   size_t *offtable = (size_t *) memory;