Skip to content

Commit 948ae06

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 <[email protected]>
1 parent 91091fb commit 948ae06

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

drivers/video/video_sw_generator.c

+30-15
Original file line numberDiff line numberDiff line change
@@ -131,25 +131,40 @@ static void video_sw_generator_fill_colorbar(struct video_sw_generator_data *dat
131131
struct video_buffer *vbuf)
132132
{
133133
int bw = data->fmt.width / 8;
134-
int h, w, i = 0;
135-
136-
for (h = 0; h < data->fmt.height; h++) {
137-
for (w = 0; w < data->fmt.width; w++) {
138-
int color_idx = data->ctrl_vflip ? 7 - w / bw : w / bw;
139-
if (data->fmt.pixelformat == VIDEO_PIX_FMT_RGB565) {
140-
uint16_t *pixel = (uint16_t *)&vbuf->buffer[i];
141-
*pixel = rgb565_colorbar_value[color_idx];
142-
i += 2;
143-
} else if (data->fmt.pixelformat == VIDEO_PIX_FMT_XRGB32) {
144-
uint32_t *pixel = (uint32_t *)&vbuf->buffer[i];
145-
*pixel = xrgb32_colorbar_value[color_idx];
146-
i += 4;
147-
}
134+
135+
vbuf->bytesused = 0;
136+
137+
if (vbuf->size < data->fmt.pitch) {
138+
LOG_WRN("Buffer %p has only %u bytes, shorter than pitch %u",
139+
vbuf, vbuf->size, data->fmt.pitch);
140+
return;
141+
}
142+
143+
/* Generate the first line of data */
144+
for (int w = 0, i = 0; w < data->fmt.width; w++) {
145+
int color_idx = data->ctrl_vflip ? 7 - w / bw : w / bw;
146+
147+
if (data->fmt.pixelformat == VIDEO_PIX_FMT_RGB565) {
148+
uint16_t *pixel = (uint16_t *)&vbuf->buffer[i];
149+
*pixel = sys_cpu_to_le16(rgb565_colorbar_value[color_idx]);
150+
} else if (data->fmt.pixelformat == VIDEO_PIX_FMT_XRGB32) {
151+
uint32_t *pixel = (uint32_t *)&vbuf->buffer[i];
152+
*pixel = sys_cpu_to_le32(xrgb32_colorbar_value[color_idx]);
153+
}
154+
i += video_bits_per_pixel(data->fmt.pixelformat) / BITS_PER_BYTE;
155+
}
156+
157+
/* Duplicate the first line all over the buffer */
158+
for (int h = 1; h < data->fmt.height; h++) {
159+
if (vbuf->size < vbuf->bytesused + data->fmt.pitch) {
160+
break;
148161
}
162+
163+
memcpy(vbuf->buffer + h * data->fmt.pitch, vbuf->buffer, data->fmt.pitch);
164+
vbuf->bytesused += data->fmt.pitch;
149165
}
150166

151167
vbuf->timestamp = k_uptime_get_32();
152-
vbuf->bytesused = i;
153168
vbuf->line_offset = 0;
154169
}
155170

0 commit comments

Comments
 (0)