Merge lp:~jamesodhunt/libnih/fix-for-bug-834813 into lp:libnih

Proposed by James Hunt
Status: Merged
Merged at revision: 1053
Proposed branch: lp:~jamesodhunt/libnih/fix-for-bug-834813
Merge into: lp:libnih
Diff against target: 440 lines (+396/-1)
3 files modified
ChangeLog (+8/-0)
nih/string.c (+8/-1)
nih/tests/test_string.c (+380/-0)
To merge this branch: bzr merge lp:~jamesodhunt/libnih/fix-for-bug-834813
Reviewer Review Type Date Requested Status
Scott James Remnant Pending
Review via email: mp+73575@code.launchpad.net

This proposal supersedes a proposal from 2011-08-31.

Description of the change

Final attempt I hope.

  * ChangeLog: updated.
  * nih/string.c (nih_str_split): Fixes to avoid over-running
    input string and also returning an empty string array entry
    when repeat is true (LP: #834813).
  * nih/tests/test_string.c (test_str_split): Added a lot of new
    tests for nih_str_split().

To post a comment you must log in.
Revision history for this message
Scott James Remnant (scott) wrote : Posted in a previous version of this proposal

"str && *str" shouldn't be necessary, this function already asserts "str != NULL"

Have you checked other uses of strchr() in the code, I probably make the same mistake all over the place - believing it would return NULL if given '\0'

I'd like that final if() cleaned up, it doesn't make sense what you're doing there - perhaps splitting out some informationally named temporary variables and checking those would make more sense, or using some other method

review: Needs Fixing
Revision history for this message
James Hunt (jamesodhunt) wrote : Posted in a previous version of this proposal

> "str && *str" shouldn't be necessary, this function already asserts "str !=
> NULL"
>
> Have you checked other uses of strchr() in the code, I probably make the same
> mistake all over the place - believing it would return NULL if given '\0'
>
> I'd like that final if() cleaned up, it doesn't make sense what you're doing
> there - perhaps splitting out some informationally named temporary variables
> and checking those would make more sense, or using some other method
Hi Scott,

Firstly, I've raised a bug on strchr(3) and memchr(3) since they do not currently specify the behaviour should the char to search for be '\0':

https://bugzilla.kernel.org/show_bug.cgi?id=42042

I've reworked (simplified) the change to nih_str_split(). Note that the "continue" is safe since we consume any and all multiple delimiter characters on the next loop iteration.

The assert protects the function initially, but since we're incrementing 'str' we do need atleast the first "str && *str" check...

   while (repeat && str && *str && strchr (delim, *str))

...since without it, we overrun the string, and the new tests will fail. The subsequent "str && *str"'s may not be strictly required, but as this bug was rather subtle anyway, I'd be tempted to err on the side of caution.

I'll resubmit the MP...

Cheers,

James.

Revision history for this message
Scott James Remnant (scott) wrote : Posted in a previous version of this proposal
Download full text (18.3 KiB)

str can never turn to NULL as a result of incrementing

On Tue, Aug 30, 2011 at 7:33 AM, James Hunt <email address hidden>wrote:

> James Hunt has proposed merging lp:~jamesodhunt/libnih/fix-for-bug-834813
> into lp:libnih.
>
> Requested reviews:
> Scott James Remnant (scott)
>
> For more details, see:
>
> https://code.launchpad.net/~jamesodhunt/libnih/fix-for-bug-834813/+merge/73383
>
> * ChangeLog: updated.
> * nih/string.c (nih_str_split): Fixes to avoid over-running
> input string and also returning an empty string array entry
> when repeat is true (LP: #834813).
> * nih/tests/test_string.c (test_str_split): Added a lot of new
> tests for nih_str_split().
>
> --
>
> https://code.launchpad.net/~jamesodhunt/libnih/fix-for-bug-834813/+merge/73383
> You are requested to review the proposed merge of
> lp:~jamesodhunt/libnih/fix-for-bug-834813 into lp:libnih.
>
> === modified file 'ChangeLog'
> --- ChangeLog 2011-08-26 18:31:43 +0000
> +++ ChangeLog 2011-08-30 14:33:16 +0000
> @@ -1,3 +1,4 @@
> +<<<<<<< TREE
> 2011-08-26 James Hunt <email address hidden>
>
> * nih/io.c (nih_io_select_fds): Ensure number of fds being managed
> @@ -6,6 +7,16 @@
> * nih/config.c, nih/error.h, nih/io.c, nih/test_files.h: Correct
> typos in comments.
>
> +=======
> +2011-08-30 James Hunt <email address hidden>
> +
> + * nih/string.c (nih_str_split): Fixes to avoid over-running
> + input string and also returning an empty string array entry
> + when repeat is true (LP: #834813).
> + * nih/tests/test_string.c (test_str_split): Added a lot of new
> + tests for nih_str_split().
> +
> +>>>>>>> MERGE-SOURCE
> 2011-06-20 James Hunt <email address hidden>
>
> * nih/watch.c (nih_watch_handle): Handle non-directory watches;
>
> === modified file 'nih/string.c'
> --- nih/string.c 2009-06-23 09:29:37 +0000
> +++ nih/string.c 2011-08-30 14:33:16 +0000
> @@ -403,17 +403,29 @@
>
> while (*str) {
> const char *ptr;
> + size_t toklen;
>
> - /* Skip initial delimiters */
> - while (repeat && strchr (delim, *str))
> + /* Skip initial delimiters taking care not to walk
> + * beyond the end of the string
> + */
> + while (repeat && str && *str && strchr (delim, *str))
> str++;
>
> /* Find the end of the token */
> ptr = str;
> - while (*str && (! strchr (delim, *str)))
> + while (str && *str && (! strchr (delim, *str)))
> str++;
>
> - if (! nih_str_array_addn (&array, parent, &len,
> + toklen = str - ptr;
> +
> + /* Don't create an empty string array element in repeat
> + * mode if there is no token (as a result of a
> + * duplicated delimiter character).
> + */
> + if (repeat && !toklen)
> + continue;
> +
> + if (str && ! nih_str_array_addn (&array, parent, &len,
> ptr, str ...

Revision history for this message
Scott James Remnant (scott) wrote : Posted in a previous version of this proposal
Download full text (19.0 KiB)

Last comments are all nits (I promise!)

ChangeLog has merge markers in the review diff;

and today is now the 31st, so this needs a ChangeLog header of its own.

- /* Skip initial delimiters */
- while (repeat && strchr (delim, *str))
+ /* Skip initial delimiters taking care not to walk
+ * beyond the end of the string
+ */

There's no need to change this comment, leave it as it is.

+ toklen = str - ptr;
+
+ /* Don't create an empty string array element in repeat
+ * mode if there is no token (as a result of a
+ * duplicated delimiter character).
+ */
+ if (repeat && !toklen)
+ continue;
+

Calculating the length of the token and checking it is completely
unnecessary. A much better check would be:

  if (repeat && (str == ptr))

This is much clearer that you mean "if we're repeating, and the end of the
string is the start"

On Wed, Aug 31, 2011 at 10:02 AM, James Hunt <email address hidden>wrote:

> James Hunt has proposed merging lp:~jamesodhunt/libnih/fix-for-bug-834813
> into lp:libnih.
>
> Requested reviews:
> Scott James Remnant (scott)
>
> For more details, see:
>
> https://code.launchpad.net/~jamesodhunt/libnih/fix-for-bug-834813/+merge/73560
>
> Take 3... :-)
>
> * ChangeLog: updated.
> * nih/string.c (nih_str_split): Fixes to avoid over-running
> input string and also returning an empty string array entry
> when repeat is true (LP: #834813).
> * nih/tests/test_string.c (test_str_split): Added a lot of new
> tests for nih_str_split().
>
> --
>
> https://code.launchpad.net/~jamesodhunt/libnih/fix-for-bug-834813/+merge/73560
> You are requested to review the proposed merge of
> lp:~jamesodhunt/libnih/fix-for-bug-834813 into lp:libnih.
>
> === modified file 'ChangeLog'
> --- ChangeLog 2011-08-26 18:31:43 +0000
> +++ ChangeLog 2011-08-31 17:02:23 +0000
> @@ -1,3 +1,4 @@
> +<<<<<<< TREE
> 2011-08-26 James Hunt <email address hidden>
>
> * nih/io.c (nih_io_select_fds): Ensure number of fds being managed
> @@ -6,6 +7,16 @@
> * nih/config.c, nih/error.h, nih/io.c, nih/test_files.h: Correct
> typos in comments.
>
> +=======
> +2011-08-31 James Hunt <email address hidden>
> +
> + * nih/string.c (nih_str_split): Fixes to avoid over-running
> + input string and also returning an empty string array entry
> + when repeat is true (LP: #834813).
> + * nih/tests/test_string.c (test_str_split): Added a lot of new
> + tests for nih_str_split().
> +
> +>>>>>>> MERGE-SOURCE
> 2011-06-20 James Hunt <email address hidden>
>
> * nih/watch.c (nih_watch_handle): Handle non-directory watches;
>
> === modified file 'nih/string.c'
> --- nih/string.c 2009-06-23 09:29:37 +0000
> +++ nih/string.c 2011-08-31 17:02:23 +0000
> @@ -403,9 +403,12 @@
>
> while (*str) {
> const char *ptr;
> + size_t toklen;
>
> - /* Skip initial delimiters */
> - while (repeat && strchr (delim, *str))
> + /* Skip initi...

Revision history for this message
Scott James Remnant (scott) wrote : Posted in a previous version of this proposal

On Tue, Aug 30, 2011 at 7:33 AM, James Hunt <email address hidden>wrote:

> Firstly, I've raised a bug on strchr(3) and memchr(3) since they do not
> currently specify the behaviour should the char to search for be '\0':
>
> https://bugzilla.kernel.org/show_bug.cgi?id=42042
>
>
Interestingly the OS X man pages do specify:

     The strchr() function locates the first occurrence of c (converted to a
     char) in the string pointed to by s. The terminating null character is
     considered to be part of the string; therefore if c is `\0', the func-
     tions locate the terminating `\0'.

Scott

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2011-08-26 18:31:43 +0000
+++ ChangeLog 2011-08-31 19:05:23 +0000
@@ -1,3 +1,11 @@
12011-08-31 James Hunt <james.hunt@ubuntu.com>
2
3 * nih/string.c (nih_str_split): Fixes to avoid over-running
4 input string and also returning an empty string array entry
5 when repeat is true (LP: #834813).
6 * nih/tests/test_string.c (test_str_split): Added a lot of new
7 tests for nih_str_split().
8
12011-08-26 James Hunt <james.hunt@ubuntu.com>92011-08-26 James Hunt <james.hunt@ubuntu.com>
210
3 * nih/io.c (nih_io_select_fds): Ensure number of fds being managed11 * nih/io.c (nih_io_select_fds): Ensure number of fds being managed
412
=== modified file 'nih/string.c'
--- nih/string.c 2009-06-23 09:29:37 +0000
+++ nih/string.c 2011-08-31 19:05:23 +0000
@@ -405,7 +405,7 @@
405 const char *ptr;405 const char *ptr;
406406
407 /* Skip initial delimiters */407 /* Skip initial delimiters */
408 while (repeat && strchr (delim, *str))408 while (repeat && *str && strchr (delim, *str))
409 str++;409 str++;
410410
411 /* Find the end of the token */411 /* Find the end of the token */
@@ -413,6 +413,13 @@
413 while (*str && (! strchr (delim, *str)))413 while (*str && (! strchr (delim, *str)))
414 str++;414 str++;
415415
416 /* Don't create an empty string array element in repeat
417 * mode if there is no token (as a result of a
418 * duplicated delimiter character).
419 */
420 if (repeat && (str == ptr))
421 continue;
422
416 if (! nih_str_array_addn (&array, parent, &len,423 if (! nih_str_array_addn (&array, parent, &len,
417 ptr, str - ptr)) {424 ptr, str - ptr)) {
418 nih_free (array);425 nih_free (array);
419426
=== modified file 'nih/tests/test_string.c'
--- nih/tests/test_string.c 2009-11-28 20:25:03 +0000
+++ nih/tests/test_string.c 2011-08-31 19:05:23 +0000
@@ -619,6 +619,215 @@
619 nih_free (array);619 nih_free (array);
620 }620 }
621621
622 TEST_FEATURE ("with no repeat and multiple identical delimiter "
623 "characters at string start");
624 TEST_ALLOC_FAIL {
625 array = nih_str_split (NULL, "\t\tthis is a test", " \t", FALSE);
626
627 if (test_alloc_failed) {
628 TEST_EQ_P (array, NULL);
629 continue;
630 }
631
632 TEST_ALLOC_SIZE (array, sizeof (char *) * 7);
633 for (i = 0; i < 6; i++)
634 TEST_ALLOC_PARENT (array[i], array);
635
636 TEST_EQ_STR (array[0], "");
637 TEST_EQ_STR (array[1], "");
638 TEST_EQ_STR (array[2], "this");
639 TEST_EQ_STR (array[3], "is");
640 TEST_EQ_STR (array[4], "a");
641 TEST_EQ_STR (array[5], "test");
642 TEST_EQ_P (array[6], NULL);
643
644 nih_free (array);
645 }
646
647 TEST_FEATURE ("with no repeat and multiple different delimiter "
648 "characters at string start");
649 TEST_ALLOC_FAIL {
650 array = nih_str_split (NULL, " \tthis is a test", " \t", FALSE);
651
652 if (test_alloc_failed) {
653 TEST_EQ_P (array, NULL);
654 continue;
655 }
656
657 TEST_ALLOC_SIZE (array, sizeof (char *) * 7);
658 for (i = 0; i < 6; i++)
659 TEST_ALLOC_PARENT (array[i], array);
660
661 TEST_EQ_STR (array[0], "");
662 TEST_EQ_STR (array[1], "");
663 TEST_EQ_STR (array[2], "this");
664 TEST_EQ_STR (array[3], "is");
665 TEST_EQ_STR (array[4], "a");
666 TEST_EQ_STR (array[5], "test");
667 TEST_EQ_P (array[6], NULL);
668
669 nih_free (array);
670 }
671
672 TEST_FEATURE ("with no repeat and multiple identical delimiter "
673 "characters within string");
674 TEST_ALLOC_FAIL {
675 array = nih_str_split (NULL, "this is a\t\ttest", " \t", FALSE);
676
677 if (test_alloc_failed) {
678 TEST_EQ_P (array, NULL);
679 continue;
680 }
681
682 TEST_ALLOC_SIZE (array, sizeof (char *) * 8);
683 for (i = 0; i < 7; i++)
684 TEST_ALLOC_PARENT (array[i], array);
685
686 TEST_EQ_STR (array[0], "this");
687 TEST_EQ_STR (array[1], "is");
688 TEST_EQ_STR (array[2], "");
689 TEST_EQ_STR (array[3], "");
690 TEST_EQ_STR (array[4], "a");
691 TEST_EQ_STR (array[5], "");
692 TEST_EQ_STR (array[6], "test");
693 TEST_EQ_P (array[7], NULL);
694
695 nih_free (array);
696 }
697
698 TEST_FEATURE ("with no repeat and multiple different delimiter "
699 "characters within string");
700 TEST_ALLOC_FAIL {
701 array = nih_str_split (NULL, "this is \n\ta\ttest", " \t\n", FALSE);
702
703 if (test_alloc_failed) {
704 TEST_EQ_P (array, NULL);
705 continue;
706 }
707
708 TEST_ALLOC_SIZE (array, sizeof (char *) * 7);
709 for (i = 0; i < 6; i++)
710 TEST_ALLOC_PARENT (array[i], array);
711
712 TEST_EQ_STR (array[0], "this");
713 TEST_EQ_STR (array[1], "is");
714 TEST_EQ_STR (array[2], "");
715 TEST_EQ_STR (array[3], "");
716 TEST_EQ_STR (array[4], "a");
717 TEST_EQ_STR (array[5], "test");
718 TEST_EQ_P (array[6], NULL);
719
720 nih_free (array);
721 }
722
723 TEST_FEATURE ("with no repeat and multiple identical delimiter "
724 "characters at string end");
725 TEST_ALLOC_FAIL {
726 array = nih_str_split (NULL, "this is a test ", " \t", FALSE);
727
728 if (test_alloc_failed) {
729 TEST_EQ_P (array, NULL);
730 continue;
731 }
732
733 TEST_ALLOC_SIZE (array, sizeof (char *) * 6);
734 for (i = 0; i < 5; i++)
735 TEST_ALLOC_PARENT (array[i], array);
736
737 TEST_EQ_STR (array[0], "this");
738 TEST_EQ_STR (array[1], "is");
739 TEST_EQ_STR (array[2], "a");
740 TEST_EQ_STR (array[3], "test");
741 TEST_EQ_STR (array[4], "");
742 TEST_EQ_P (array[5], NULL);
743
744 nih_free (array);
745 }
746
747 TEST_FEATURE ("with no repeat and multiple different delimiter "
748 "characters at string end");
749 TEST_ALLOC_FAIL {
750 array = nih_str_split (NULL, "this is a test \t", " \t", FALSE);
751
752 if (test_alloc_failed) {
753 TEST_EQ_P (array, NULL);
754 continue;
755 }
756
757 TEST_ALLOC_SIZE (array, sizeof (char *) * 6);
758 for (i = 0; i < 5; i++)
759 TEST_ALLOC_PARENT (array[i], array);
760
761 TEST_EQ_STR (array[0], "this");
762 TEST_EQ_STR (array[1], "is");
763 TEST_EQ_STR (array[2], "a");
764 TEST_EQ_STR (array[3], "test");
765 TEST_EQ_STR (array[4], "");
766 TEST_EQ_P (array[5], NULL);
767
768 nih_free (array);
769 }
770
771 TEST_FEATURE ("with no repeat and multiple identical delimiter "
772 "characters at beginning, middle and end of string");
773 TEST_ALLOC_FAIL {
774 array = nih_str_split (NULL, " this is\n\n\na test\t\t\t", " \t\n", FALSE);
775
776 if (test_alloc_failed) {
777 TEST_EQ_P (array, NULL);
778 continue;
779 }
780
781 TEST_ALLOC_SIZE (array, sizeof (char *) * 12);
782 for (i = 0; i < 11; i++)
783 TEST_ALLOC_PARENT (array[i], array);
784
785 TEST_EQ_STR (array[0], "");
786 TEST_EQ_STR (array[1], "");
787 TEST_EQ_STR (array[2], "");
788 TEST_EQ_STR (array[3], "this");
789 TEST_EQ_STR (array[4], "is");
790 TEST_EQ_STR (array[5], "");
791 TEST_EQ_STR (array[6], "");
792 TEST_EQ_STR (array[7], "a");
793 TEST_EQ_STR (array[8], "test");
794 TEST_EQ_STR (array[9], "");
795 TEST_EQ_STR (array[10], "");
796 TEST_EQ_P (array[11], NULL);
797
798 nih_free (array);
799 }
800
801 TEST_FEATURE ("with no repeat and multiple different delimiter "
802 "characters at beginning, middle and end of string");
803 TEST_ALLOC_FAIL {
804 array = nih_str_split (NULL, ": \nthis is\t \n:a test:\n ", "\n :\t", FALSE);
805
806 if (test_alloc_failed) {
807 TEST_EQ_P (array, NULL);
808 continue;
809 }
810
811 TEST_ALLOC_SIZE (array, sizeof (char *) * 13);
812 for (i = 0; i < 12; i++)
813 TEST_ALLOC_PARENT (array[i], array);
814
815 TEST_EQ_STR (array[0], "");
816 TEST_EQ_STR (array[1], "");
817 TEST_EQ_STR (array[2], "");
818 TEST_EQ_STR (array[3], "this");
819 TEST_EQ_STR (array[4], "is");
820 TEST_EQ_STR (array[5], "");
821 TEST_EQ_STR (array[6], "");
822 TEST_EQ_STR (array[7], "");
823 TEST_EQ_STR (array[8], "a");
824 TEST_EQ_STR (array[9], "test");
825 TEST_EQ_STR (array[10], "");
826 TEST_EQ_STR (array[11], "");
827 TEST_EQ_P (array[12], NULL);
828
829 nih_free (array);
830 }
622831
623 /* Check that we can split a string treating multiple consecutive832 /* Check that we can split a string treating multiple consecutive
624 * matching characters as a single separator to be skipped.833 * matching characters as a single separator to be skipped.
@@ -645,6 +854,177 @@
645 nih_free (array);854 nih_free (array);
646 }855 }
647856
857 /* Check that we can split a string containing multiple
858 * occurences of one of the delimiter characters at the
859 * beginning of the string.
860 */
861 TEST_FEATURE ("with repeat and multiple identical adjacent delimiter characters at string start");
862 TEST_ALLOC_FAIL {
863 array = nih_str_split (NULL, "\n\nhello", " \t\r\n", TRUE);
864
865 if (test_alloc_failed) {
866 TEST_EQ_P (array, NULL);
867 continue;
868 }
869
870 TEST_ALLOC_SIZE (array, sizeof (char *) * 2);
871 for (i = 0; i < 1; i++)
872 TEST_ALLOC_PARENT (array[i], array);
873
874 TEST_EQ_STR (array[0], "hello");
875 TEST_EQ_P (array[1], NULL);
876
877 nih_free (array);
878 }
879
880 TEST_FEATURE ("with repeat and multiple different adjacent delimiter characters at string start");
881 TEST_ALLOC_FAIL {
882 array = nih_str_split (NULL, "\n\r hello", " \t\r\n", TRUE);
883
884 if (test_alloc_failed) {
885 TEST_EQ_P (array, NULL);
886 continue;
887 }
888
889 TEST_ALLOC_SIZE (array, sizeof (char *) * 2);
890 for (i = 0; i < 1; i++)
891 TEST_ALLOC_PARENT (array[i], array);
892
893 TEST_EQ_STR (array[0], "hello");
894 TEST_EQ_P (array[1], NULL);
895
896 nih_free (array);
897 }
898
899 TEST_FEATURE ("with repeat and multiple identical adjacent delimiter "
900 "characters within string");
901 TEST_ALLOC_FAIL {
902 array = nih_str_split (NULL, "hello\n\rworld", " \t\n\r", TRUE);
903
904 if (test_alloc_failed) {
905 TEST_EQ_P (array, NULL);
906 continue;
907 }
908
909 TEST_ALLOC_SIZE (array, sizeof (char *) * 3);
910 for (i = 0; i < 2; i++)
911 TEST_ALLOC_PARENT (array[i], array);
912
913 TEST_EQ_STR (array[0], "hello");
914 TEST_EQ_STR (array[1], "world");
915 TEST_EQ_P (array[2], NULL);
916
917 nih_free (array);
918 }
919
920 TEST_FEATURE ("with repeat and multiple different adjacent delimiter "
921 "characters within string");
922 TEST_ALLOC_FAIL {
923 array = nih_str_split (NULL, "hello\n\r\tworld", " \t\n\r", TRUE);
924
925 if (test_alloc_failed) {
926 TEST_EQ_P (array, NULL);
927 continue;
928 }
929
930 TEST_ALLOC_SIZE (array, sizeof (char *) * 3);
931 for (i = 0; i < 2; i++)
932 TEST_ALLOC_PARENT (array[i], array);
933
934 TEST_EQ_STR (array[0], "hello");
935 TEST_EQ_STR (array[1], "world");
936 TEST_EQ_P (array[2], NULL);
937
938 nih_free (array);
939 }
940
941 TEST_FEATURE ("with repeat and multiple identical adjacent delimiter "
942 "characters at string end");
943 TEST_ALLOC_FAIL {
944 array = nih_str_split (NULL, "hello\n\n\n\n\n\n\n", " \t\r\n", TRUE);
945
946 if (test_alloc_failed) {
947 TEST_EQ_P (array, NULL);
948 continue;
949 }
950
951 TEST_ALLOC_SIZE (array, sizeof (char *) * 2);
952 for (i = 0; i < 1; i++)
953 TEST_ALLOC_PARENT (array[i], array);
954
955 TEST_EQ_STR (array[0], "hello");
956 TEST_EQ_P (array[1], NULL);
957
958 nih_free (array);
959 }
960
961 TEST_FEATURE ("with repeat and multiple different adjacent delimiter "
962 "characters at string end");
963 TEST_ALLOC_FAIL {
964 array = nih_str_split (NULL, "hello \r\t\r\t\n ", " \t\r\n", TRUE);
965
966 if (test_alloc_failed) {
967 TEST_EQ_P (array, NULL);
968 continue;
969 }
970
971 TEST_ALLOC_SIZE (array, sizeof (char *) * 2);
972 for (i = 0; i < 1; i++)
973 TEST_ALLOC_PARENT (array[i], array);
974
975 TEST_EQ_STR (array[0], "hello");
976 TEST_EQ_P (array[1], NULL);
977
978 nih_free (array);
979 }
980
981 TEST_FEATURE ("with repeat and multiple identical adjacent delimiter "
982 "characters at beginning, middle and end of string");
983 TEST_ALLOC_FAIL {
984 array = nih_str_split (NULL,
985 " hello\n\n\n, world\n\n\n",
986 "\r\t\n ", TRUE);
987
988 if (test_alloc_failed) {
989 TEST_EQ_P (array, NULL);
990 continue;
991 }
992
993 TEST_ALLOC_SIZE (array, sizeof (char *) * 4);
994 for (i = 0; i < 3; i++)
995 TEST_ALLOC_PARENT (array[i], array);
996
997 TEST_EQ_STR (array[0], "hello");
998 TEST_EQ_STR (array[1], ",");
999 TEST_EQ_STR (array[2], "world");
1000 TEST_EQ_P (array[3], NULL);
1001
1002 nih_free (array);
1003 }
1004
1005 TEST_FEATURE ("with repeat and multiple different adjacent delimiter "
1006 "characters at beginning, middle and end of string");
1007 TEST_ALLOC_FAIL {
1008 array = nih_str_split (NULL,
1009 "\n \r\thello\n\n\r , \n\t\rworld\t \r\n \n",
1010 " \t\n\r", TRUE);
1011
1012 if (test_alloc_failed) {
1013 TEST_EQ_P (array, NULL);
1014 continue;
1015 }
1016
1017 TEST_ALLOC_SIZE (array, sizeof (char *) * 4);
1018 for (i = 0; i < 3; i++)
1019 TEST_ALLOC_PARENT (array[i], array);
1020
1021 TEST_EQ_STR (array[0], "hello");
1022 TEST_EQ_STR (array[1], ",");
1023 TEST_EQ_STR (array[2], "world");
1024 TEST_EQ_P (array[3], NULL);
1025
1026 nih_free (array);
1027 }
6481028
649 /* Check that we can give an empty string, and end up with a1029 /* Check that we can give an empty string, and end up with a
650 * one-element array that only contains a NULL pointer.1030 * one-element array that only contains a NULL pointer.

Subscribers

People subscribed via source and target branches