Add test case and fix for string with broken escape sequences

This commit is contained in:
Thomas Jensen 2023-05-01 14:18:33 +02:00
parent 34759334f7
commit c41997870e
No known key found for this signature in database
GPG Key ID: A4ACEE270D0FB7DB
5 changed files with 45 additions and 4 deletions

View File

@ -165,7 +165,7 @@ uint32_t *advance_next32(const uint32_t *s, size_t *invis)
/* Found '[' char after ESC. A CSI sequence has started. */
(*invis)++;
ansipos++;
} else if (ansipos == 1 && c >= 0x40 && c <= 0x5f) {
} else if (ansipos == 1 && c >= 0x40 && c <= 0x5f) { /* between '@' and '_' (mostly uppercase letters) */
/* Found a byte designating the end of a two-byte escape sequence */
(*invis)++;
ansipos = 0;
@ -183,6 +183,9 @@ uint32_t *advance_next32(const uint32_t *s, size_t *invis)
break;
}
}
if (rest == NULL) {
rest = s + u32_strlen(s);
}
return (uint32_t *) rest;
}

View File

@ -137,7 +137,7 @@ ucs4_t to_utf32(char ascii);
* @param invis Will contain the number of invisible characters skipped in order to get to the new position.
* This will be 0 unless `s` pointed to an ESC char, in which case it contains the length in characters of that
* escape sequence.
* @return The next position, or 0 if the end of the string was reached
* @return The next position, or a pointer to the terminating 0 if the end of the string was reached
*/
uint32_t *advance_next32(const uint32_t *s, size_t *invis);

View File

@ -303,6 +303,44 @@ void test_ansi_unicode_tabs(void **state)
void test_ansi_unicode_broken_escapes(void **state)
{
UNUSED(state);
/* "\x1b[38;5;203 X" is the first escape sequence, followed by
* "X " (visible) and
* "\x1b[0m" (regular escape sequence) and
* "__" (visible)
* "\x1b[38;5;203m" (regular, invisible)
* "b" (visible)
* "\x1b[" (broken, counts as invisible, and belonging to the previous 'b')
*/
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203 XX \x1b[0m__\x1b[38;5;203mb\x1b[", "ASCII");
fprintf(stderr, "BOO\n");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
fprintf(stderr, "BAA\n");
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("X __b", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(5, (int) actual->num_columns);
assert_int_equal(34, (int) actual->num_chars);
assert_int_equal(5, (int) actual->num_chars_visible);
assert_int_equal(29, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 13, 18, 19, 20, 34};
assert_array_equal(expected_firstchar_idx, actual->first_char, 6);
int expected_vischar_idx[] = {12, 13, 18, 19, 31, 34};
assert_array_equal(expected_vischar_idx, actual->visible_char, 6);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_null(void **state)
{
UNUSED(state);
@ -935,8 +973,6 @@ void test_bxs_valid_in_filename_error(void **state)
}
// TODO test case for incomplete/broken escape sequences
void test_bxs_free_null(void **state)
{

View File

@ -33,6 +33,7 @@ void test_ansi_unicode_blanks(void **state);
void test_ansi_unicode_invisible_only(void **state);
void test_ansi_unicode_illegalchar(void **state);
void test_ansi_unicode_tabs(void **state);
void test_ansi_unicode_broken_escapes(void **state);
void test_ansi_unicode_null(void **state);
void test_bxs_strdup(void **state);

View File

@ -128,6 +128,7 @@ int main(void)
cmocka_unit_test_setup(test_ansi_unicode_invisible_only, beforeTest),
cmocka_unit_test_setup(test_ansi_unicode_illegalchar, beforeTest),
cmocka_unit_test_setup(test_ansi_unicode_tabs, beforeTest),
cmocka_unit_test_setup(test_ansi_unicode_broken_escapes, beforeTest),
cmocka_unit_test_setup(test_ansi_unicode_null, beforeTest),
cmocka_unit_test_setup(test_bxs_strdup, beforeTest),
cmocka_unit_test_setup(test_bxs_trimdup_null, beforeTest),