Skip to content

Commit 1d843e5

Browse files
committed
drivers: video: sw_generator: modify video_sw_generator_fill_colorbar()
Add a check for the array size to avoid overwriting unrelated memory when the buffer is too small for the full format. It first check if there is enough buffer for one line, and fill it programmatically. Then, it will try to duplicate that line over the entire buffer, in the limit of the room available. Signed-off-by: Josuah Demangeon <me@josuah.net>
1 parent 1881b88 commit 1d843e5

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

drivers/video/video_sw_generator.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <zephyr/drivers/video-controls.h>
1212
#include <zephyr/logging/log.h>
1313
#include <zephyr/sys/util.h>
14+
#include <zephyr/sys/byteorder.h>
1415

1516
LOG_MODULE_REGISTER(video_sw_generator, CONFIG_VIDEO_LOG_LEVEL);
1617

@@ -130,25 +131,36 @@ static void video_sw_generator_fill_colorbar(struct video_sw_generator_data *dat
130131
struct video_buffer *vbuf)
131132
{
132133
int bw = data->fmt.width / 8;
133-
int h, w, i = 0;
134-
135-
for (h = 0; h < data->fmt.height; h++) {
136-
for (w = 0; w < data->fmt.width; w++) {
137-
int color_idx = data->ctrl_vflip ? 7 - w / bw : w / bw;
138-
if (data->fmt.pixelformat == VIDEO_PIX_FMT_RGB565) {
139-
uint16_t *pixel = (uint16_t *)&vbuf->buffer[i];
140-
*pixel = rgb565_colorbar_value[color_idx];
141-
i += 2;
142-
} else if (data->fmt.pixelformat == VIDEO_PIX_FMT_XRGB32) {
143-
uint32_t *pixel = (uint32_t *)&vbuf->buffer[i];
144-
*pixel = xrgb32_colorbar_value[color_idx];
145-
i += 4;
146-
}
134+
struct video_format *fmt = &data->fmt;
135+
size_t pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;
136+
137+
vbuf->bytesused = 0;
138+
139+
/* Generate the first line of data */
140+
for (int w = 0, i = 0; w < data->fmt.width; w++) {
141+
int color_idx = data->ctrl_vflip ? 7 - w / bw : w / bw;
142+
143+
if (data->fmt.pixelformat == VIDEO_PIX_FMT_RGB565) {
144+
uint16_t *pixel = (uint16_t *)&vbuf->buffer[i];
145+
*pixel = sys_cpu_to_le16(rgb565_colorbar_value[color_idx]);
146+
} else if (data->fmt.pixelformat == VIDEO_PIX_FMT_XRGB32) {
147+
uint32_t *pixel = (uint32_t *)&vbuf->buffer[i];
148+
*pixel = sys_cpu_to_le32(xrgb32_colorbar_value[color_idx]);
147149
}
150+
i += video_bits_per_pixel(data->fmt.pixelformat) / BITS_PER_BYTE;
151+
}
152+
153+
/* Duplicate the first line all over the buffer */
154+
for (int h = 1; h < data->fmt.height; h++) {
155+
if (vbuf->size < vbuf->bytesused + pitch) {
156+
break;
157+
}
158+
159+
memcpy(vbuf->buffer + h * pitch, vbuf->buffer, pitch);
160+
vbuf->bytesused += pitch;
148161
}
149162

150163
vbuf->timestamp = k_uptime_get_32();
151-
vbuf->bytesused = i;
152164
vbuf->line_offset = 0;
153165
}
154166

0 commit comments

Comments
 (0)