mirror of
https://github.com/tmux/tmux.git
synced 2026-10-10 12:14:43 +00:00
Fix off-by-one buffer growth in sixel_print_add and add regression test.
This commit is contained in:
72
regress/image-sixel-buffer.c
Normal file
72
regress/image-sixel-buffer.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/* Exercise SIXEL output lengths at the encoder's allocation boundary. */
|
||||
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
#include "../tmux.h"
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
#include "../image-sixel.c"
|
||||
#include "../xmalloc.c"
|
||||
|
||||
/* Abort if an allocation or formatting check fails. */
|
||||
void
|
||||
fatal(__unused const char *fmt, ...)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Abort if an allocation or formatting check fails. */
|
||||
void
|
||||
fatalx(__unused const char *fmt, ...)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Encode lengths below, at and above the initial 8192-byte allocation. */
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
struct sixel_image image = { 0 };
|
||||
u_int colour, width, x;
|
||||
size_t size;
|
||||
char *data;
|
||||
|
||||
colour = (2u << 25) | (100u << 16) | (100u << 8) | 100u;
|
||||
image.sy = 2;
|
||||
image.ncolours = 1;
|
||||
image.used_colours = 1;
|
||||
image.colours = &colour;
|
||||
image.lines = xcalloc(2, sizeof *image.lines);
|
||||
|
||||
/* Headers and controls add 26 bytes to these uncompressed rasters. */
|
||||
for (width = 8165; width <= 8167; width++) {
|
||||
image.sx = width;
|
||||
image.lines[0].sx = width;
|
||||
image.lines[1].sx = width;
|
||||
image.lines[0].pixels = xcalloc(width, sizeof(uint16_t));
|
||||
image.lines[1].pixels = xcalloc(width, sizeof(uint16_t));
|
||||
|
||||
/* Alternate row bits so adjacent columns cannot be compressed. */
|
||||
for (x = 0; x < width; x++)
|
||||
image.lines[x % 2].pixels[x] = 1;
|
||||
data = sixel_print(&image, NULL, &size);
|
||||
assert(data != NULL);
|
||||
assert(size == width + 26);
|
||||
assert(data[size] == '\0');
|
||||
assert(strlen(data) == size);
|
||||
free(data);
|
||||
free(image.lines[0].pixels);
|
||||
free(image.lines[1].pixels);
|
||||
}
|
||||
free(image.lines);
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
/* Skip the encoder check when image support is disabled. */
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
15
regress/image-sixel-buffer.mk
Normal file
15
regress/image-sixel-buffer.mk
Normal file
@@ -0,0 +1,15 @@
|
||||
# Use the configured compiler and flags for the standalone encoder check.
|
||||
|
||||
.PHONY: sixel-buffer-probe sixel-buffer-test
|
||||
|
||||
sixel-buffer-probe:
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -fsanitize=address \
|
||||
-o "$(SIXEL_TEST_DIR)/probe" "$(SIXEL_TEST_DIR)/probe.c"
|
||||
|
||||
sixel-buffer-test:
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -UNDEBUG \
|
||||
-ffunction-sections -fdata-sections -fsanitize=address \
|
||||
-fno-omit-frame-pointer $(SIXEL_TEST_LDFLAGS) $(LDFLAGS) \
|
||||
-o "$(SIXEL_TEST_DIR)/test" "$(srcdir)/regress/image-sixel-buffer.c" \
|
||||
"$(srcdir)/compat/reallocarray.c"
|
||||
32
regress/image-sixel-buffer.sh
Normal file
32
regress/image-sixel-buffer.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Catch a trailing NUL written beyond an exactly full SIXEL output buffer.
|
||||
|
||||
PATH=/bin:/usr/bin
|
||||
export PATH
|
||||
|
||||
SIXEL_TEST_DIR=$(mktemp -d) || exit 1
|
||||
trap 'rm -rf "$SIXEL_TEST_DIR"' 0 1 15
|
||||
export SIXEL_TEST_DIR
|
||||
ASAN_OPTIONS=detect_leaks=0
|
||||
export ASAN_OPTIONS
|
||||
|
||||
case $(uname -s) in
|
||||
Darwin) SIXEL_TEST_LDFLAGS=-Wl,-dead_strip ;;
|
||||
*) SIXEL_TEST_LDFLAGS=-Wl,--gc-sections ;;
|
||||
esac
|
||||
export SIXEL_TEST_LDFLAGS
|
||||
|
||||
# Skip when the configured compiler or its runtime cannot use ASan.
|
||||
printf 'int main(void) { return 0; }\n' >"$SIXEL_TEST_DIR/probe.c"
|
||||
if ! make -s -C .. -f Makefile -f regress/image-sixel-buffer.mk \
|
||||
sixel-buffer-probe >"$SIXEL_TEST_DIR/probe.log" 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
if ! "$SIXEL_TEST_DIR/probe" >"$SIXEL_TEST_DIR/probe.log" 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
make -s -C .. -f Makefile -f regress/image-sixel-buffer.mk \
|
||||
sixel-buffer-test || exit 1
|
||||
"$SIXEL_TEST_DIR/test" || exit 1
|
||||
Reference in New Issue
Block a user