Handle empty strings correctly.
authorBruno Haible <bruno@clisp.org>
Sun, 22 Feb 2009 12:15:52 +0000 (13:15 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 22 Feb 2009 12:15:52 +0000 (13:15 +0100)
14 files changed:
ChangeLog
lib/uninorm/u-normalize-internal.h
tests/uninorm/test-u16-nfc.c
tests/uninorm/test-u16-nfd.c
tests/uninorm/test-u16-nfkc.c
tests/uninorm/test-u16-nfkd.c
tests/uninorm/test-u32-nfc.c
tests/uninorm/test-u32-nfd.c
tests/uninorm/test-u32-nfkc.c
tests/uninorm/test-u32-nfkd.c
tests/uninorm/test-u8-nfc.c
tests/uninorm/test-u8-nfd.c
tests/uninorm/test-u8-nfkc.c
tests/uninorm/test-u8-nfkd.c

index 43b2c8f0b41f1a72a04a09cf7a24d419685662c1..4a07193d4c6561ae0b640b4c088a55b329345de8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2009-02-22  Bruno Haible  <bruno@clisp.org>
+
+       * lib/uninorm/u-normalize-internal.h (FUNC): At the end, handle
+       zero-length results and shrink excess allocated memory.
+       * tests/uninorm/test-u8-nfc.c (test_u8_nfc): Check empty string result.
+       * tests/uninorm/test-u8-nfd.c (test_u8_nfd): Likewise.
+       * tests/uninorm/test-u8-nfkc.c (test_u8_nfkc): Likewise.
+       * tests/uninorm/test-u8-nfkd.c (test_u8_nfkd): Likewise.
+       * tests/uninorm/test-u16-nfc.c (test_u16_nfc): Likewise.
+       * tests/uninorm/test-u16-nfd.c (test_u16_nfd): Likewise.
+       * tests/uninorm/test-u16-nfkc.c (test_u16_nfkc): Likewise.
+       * tests/uninorm/test-u16-nfkd.c (test_u16_nfkd): Likewise.
+       * tests/uninorm/test-u32-nfc.c (test_u32_nfc): Likewise.
+       * tests/uninorm/test-u32-nfd.c (test_u32_nfd): Likewise.
+       * tests/uninorm/test-u32-nfkc.c (test_u32_nfkc): Likewise.
+       * tests/uninorm/test-u32-nfkd.c (test_u32_nfkd): Likewise.
+
 2009-02-21  Bruno Haible  <bruno@clisp.org>
 
        * doc/gnulib.texi: Include safe-alloc.texi earlier.
index 7dc83ad9d2fd0b115a756ae44e8ae629a5b9475e..70c325513e931f07bb2a1acf8a0485e758763ba8 100644 (file)
@@ -331,6 +331,29 @@ FUNC (uninorm_t nf, const UNIT *s, size_t n,
       }
   }
 
+  if (length == 0)
+    {
+      if (result == NULL)
+       {
+         /* Return a non-NULL value.  NULL means error.  */
+         result = (UNIT *) malloc (1);
+         if (result == NULL)
+           {
+             errno = ENOMEM;
+             goto fail;
+           }
+       }
+    }
+  else if (result != resultbuf && length < allocated)
+    {
+      /* Shrink the allocated memory if possible.  */
+      UNIT *memory;
+
+      memory = (UNIT *) realloc (result, length * sizeof (UNIT));
+      if (memory != NULL)
+       result = memory;
+    }
+
   if (sortbuf_count > 0)
     abort ();
   if (sortbuf != sortbuf_preallocated)
index 397914c5f4c1ec187eab8ac625bcbb312bde16f4..70767df5af5b31ad26baa1baa794509c3784236d 100644 (file)
@@ -103,6 +103,9 @@ check (const uint16_t *input, size_t input_length,
 void
 test_u16_nfc (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint16_t input[]    = { 0x0020 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 84499f0d3722c54084356853ac8c7eb5235f8506..161abd47408255f0c24b58ae532c1b691d95a851 100644 (file)
@@ -103,6 +103,9 @@ check (const uint16_t *input, size_t input_length,
 void
 test_u16_nfd (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint16_t input[]    = { 0x0020 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index aa7bc2ceef771371b06eb22fbfc70deda61c9bf4..df648044824cf1311014b37e362d67ff0e1fd002 100644 (file)
@@ -103,6 +103,9 @@ check (const uint16_t *input, size_t input_length,
 void
 test_u16_nfkc (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint16_t input[]    = { 0x0020 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 3cc1fac8fc0fabe53d2128c4db1012cba0571bba..587a704ae687dc3731cc7558a59b90486e37ced3 100644 (file)
@@ -103,6 +103,9 @@ check (const uint16_t *input, size_t input_length,
 void
 test_u16_nfkd (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint16_t input[]    = { 0x0020 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 0c7cd790fc4e57484908d8e433b997531464d0dd..3aafb96a8a6d398f2006058d8ff4f4733967cc11 100644 (file)
@@ -103,6 +103,9 @@ check (const uint32_t *input, size_t input_length,
 void
 test_u32_nfc (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint32_t input[]    = { 0x0020 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 9aa820a3db4f0c2682b6ac8044d6c97a1833cb95..426ad9dd56394dc7f3640bc62e0f84cb379654ec 100644 (file)
@@ -103,6 +103,9 @@ check (const uint32_t *input, size_t input_length,
 void
 test_u32_nfd (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint32_t input[]    = { 0x0020 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 0ef65f5935b0ca5049c359e6f8eec7c8b677b222..831e490a45ab03b5ca7693d10434320b911559af 100644 (file)
@@ -103,6 +103,9 @@ check (const uint32_t *input, size_t input_length,
 void
 test_u32_nfkc (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint32_t input[]    = { 0x0020 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 17768f74bad2492c70474059cf10ad9edaa30cb1..408c593b0b0b055089a31013ac0c0a01e2a73b03 100644 (file)
@@ -103,6 +103,9 @@ check (const uint32_t *input, size_t input_length,
 void
 test_u32_nfkd (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint32_t input[]    = { 0x0020 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 0e191570893c1c0bb5db5dd2e106be80fe1963e6..5a86e59f26aa9e982f6c1d979639a6b4e44b7630 100644 (file)
@@ -103,6 +103,9 @@ check (const uint8_t *input, size_t input_length,
 void
 test_u8_nfc (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint8_t input[]    = { 0x20 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 9dfde02c23dd3e3bf5a0c8fdaeabdeb479f20bf7..2338e8f8f608dd9898eebf6659670628020237ba 100644 (file)
@@ -103,6 +103,9 @@ check (const uint8_t *input, size_t input_length,
 void
 test_u8_nfd (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint8_t input[]    = { 0x20 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index 6792e826d4dfb0366642245d84a485a56d193ebb..1d9f0e1a98a8e62cb83951785d50191bec348f19 100644 (file)
@@ -103,6 +103,9 @@ check (const uint8_t *input, size_t input_length,
 void
 test_u8_nfkc (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint8_t input[]    = { 0x20 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);
index c2a2d14536a8937ad5d7289c6a7f76639ef58610..498f42e4bd2e85af7c6178b62260620ed2c535e9 100644 (file)
@@ -103,6 +103,9 @@ check (const uint8_t *input, size_t input_length,
 void
 test_u8_nfkd (void)
 {
+  { /* Empty string.  */
+    ASSERT (check (NULL, 0, NULL, 0) == 0);
+  }
   { /* SPACE */
     static const uint8_t input[]    = { 0x20 };
     ASSERT (check (input, SIZEOF (input), input, SIZEOF (input)) == 0);