Skip to content

Commit

Permalink
send non-printable codepoints as U+FFFD
Browse files Browse the repository at this point in the history
  • Loading branch information
adsr committed Jul 27, 2024
1 parent aaf10e7 commit 7516dea
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
13 changes: 7 additions & 6 deletions termbox2.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ SOFTWARE.
#include <termios.h>
#include <unistd.h>
#include <wchar.h>
#include <wctype.h>

#ifdef PATH_MAX
#define TB_PATH_MAX PATH_MAX
Expand Down Expand Up @@ -493,6 +494,9 @@ int tb_hide_cursor(void);
*
* Function tb_extend_cell() is a shortcut for appending 1 codepoint to
* cell->ech.
*
* Non-printable (`iswprint(3)`) codepoints are replaced with U+FFFD at render
* time.
*/
int tb_set_cell(int x, int y, uint32_t ch, uintattr_t fg, uintattr_t bg);
int tb_set_cell_ex(int x, int y, uint32_t *ch, size_t nch, uintattr_t fg,
Expand Down Expand Up @@ -3224,13 +3228,10 @@ static int send_cluster(int x, int y, uint32_t *ch, size_t nch) {
int i;
for (i = 0; i < (int)nch; i++) {
uint32_t ch32 = *(ch + i);
int chu8_len;
if (ch32 == 0) { // replace null with space (from termbox 19dbee5)
chu8_len = 1;
chu8[0] = ' ';
} else {
chu8_len = tb_utf8_unicode_to_char(chu8, ch32);
if (!iswprint((wint_t)ch32)) {
ch32 = 0xfffd; // replace non-printable codepoints with U+FFFD
}
int chu8_len = tb_utf8_unicode_to_char(chu8, ch32);
if_err_return(rv, bytebuf_nputs(&global.out, chu8, (size_t)chu8_len));
}

Expand Down
2 changes: 1 addition & 1 deletion tests/test_invalid_utf8/expected.ansi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#5foo�

#5�



Expand Down
6 changes: 5 additions & 1 deletion tests/test_invalid_utf8/test.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
declare(strict_types=1);

$test->ffi->tb_init();
$test->ffi->tb_print_ex(0, 0, 0, 0, NULL, "foo\xc2\x00password");

$y = 0;
$test->ffi->tb_print_ex(0, $y++, 0, 0, NULL, "foo\xc2\x00password"); // stop at NULL
$test->ffi->tb_set_cell(0, $y++, 0xffff, 0, 0); // invalid codepoint

$test->ffi->tb_present();

$test->screencap();
24 changes: 24 additions & 0 deletions tests/test_non_printable/expected.ansi
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#50x00 �
#50x01 �
#50x08 �
#50x09 �
#50x0a �
#50x1f �
#50x7f �

















25 changes: 25 additions & 0 deletions tests/test_non_printable/test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);

$test->ffi->tb_init();

$codepoints = [
0x00, // NULL
0x01, // control code
0x08, // backspace
0x09, // tab
0x0a, // newline
0x1f, // control code
0x7f, // delete
];

$y = 0;
foreach ($codepoints as $ch) {
$test->ffi->tb_printf(0, $y, 0, 0, "0x%02x ", $ch);
$test->ffi->tb_set_cell(5, $y, $ch, 0, 0);
$y += 1;
}

$test->ffi->tb_present();

$test->screencap();

0 comments on commit 7516dea

Please sign in to comment.