ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
network/frame_validator.c
Go to the documentation of this file.
1
7#include <ascii-chat/network/frame_validator.h>
8#include <ascii-chat/network/network.h>
9#include <ascii-chat/asciichat_errno.h>
10#include <ascii-chat/util/format.h>
11#include <ascii-chat/util/endian.h>
12#include <ascii-chat/video/image.h>
13#include <string.h>
14
15asciichat_error_t frame_check_size_overflow(size_t header_size, size_t data_size) {
16 if (data_size > SIZE_MAX - header_size) {
17 char size_str[32];
18 format_bytes_pretty(data_size, size_str, sizeof(size_str));
19 SET_ERRNO(ERROR_BUFFER_OVERFLOW, "Frame size overflow: %s", size_str);
20 return ERROR_BUFFER_OVERFLOW;
21 }
22 return ASCIICHAT_OK;
23}
24
25asciichat_error_t frame_validate_legacy(size_t len, size_t expected_rgb_size) {
26 // Check minimum header size
27 if (len < FRAME_HEADER_SIZE_LEGACY) {
28 SET_ERRNO(ERROR_INVALID_FRAME, "Legacy frame header too small: %zu bytes", len);
29 return ERROR_INVALID_FRAME;
30 }
31
32 // Check for overflow
33 asciichat_error_t err = frame_check_size_overflow(FRAME_HEADER_SIZE_LEGACY, expected_rgb_size);
34 if (err != ASCIICHAT_OK) {
35 return err;
36 }
37
38 size_t expected_total = FRAME_HEADER_SIZE_LEGACY + expected_rgb_size;
39 if (len != expected_total) {
40 SET_ERRNO(ERROR_INVALID_FRAME, "Legacy frame length mismatch: expected %zu got %zu", expected_total, len);
41 return ERROR_INVALID_FRAME;
42 }
43
44 return ASCIICHAT_OK;
45}
46
47asciichat_error_t frame_validate_new(void *data, size_t len, bool *out_compressed, uint32_t *out_data_size) {
48 // Check minimum new format header size
49 if (len < FRAME_HEADER_SIZE_NEW) {
50 SET_ERRNO(ERROR_INVALID_FRAME, "New frame header too small: %zu bytes", len);
51 return ERROR_INVALID_FRAME;
52 }
53
54 uint32_t compressed_flag, data_size;
55 frame_extract_new_header(data, &compressed_flag, &data_size);
56
57 size_t data_size_sz = (size_t)data_size;
58
59 // Check data size against maximum
60 if (data_size_sz > IMAGE_MAX_PIXELS_SIZE) {
61 char size_str[32];
62 format_bytes_pretty(data_size_sz, size_str, sizeof(size_str));
63 SET_ERRNO(ERROR_INVALID_FRAME, "Frame data too large: %s", size_str);
64 return ERROR_INVALID_FRAME;
65 }
66
67 // Check for overflow
68 asciichat_error_t err = frame_check_size_overflow(FRAME_HEADER_SIZE_NEW, data_size_sz);
69 if (err != ASCIICHAT_OK) {
70 return err;
71 }
72
73 size_t expected_total = FRAME_HEADER_SIZE_NEW + data_size_sz;
74 if (len != expected_total) {
75 SET_ERRNO(ERROR_INVALID_FRAME, "New frame length mismatch: expected %zu got %zu", expected_total, len);
76 return ERROR_INVALID_FRAME;
77 }
78
79 if (out_compressed)
80 *out_compressed = (compressed_flag != 0);
81 if (out_data_size)
82 *out_data_size = data_size;
83 return ASCIICHAT_OK;
84}
85
86void frame_extract_dimensions(const void *data, uint32_t *width, uint32_t *height) {
87 uint32_t width_net, height_net;
88 memcpy(&width_net, data, FRAME_HEADER_FIELD_SIZE);
89 memcpy(&height_net, (char *)data + FRAME_HEADER_FIELD_SIZE, FRAME_HEADER_FIELD_SIZE);
90 *width = NET_TO_HOST_U32(width_net);
91 *height = NET_TO_HOST_U32(height_net);
92}
93
94void frame_extract_new_header(const void *data, uint32_t *compressed, uint32_t *data_size) {
95 uint32_t compressed_net, size_net;
96 memcpy(&compressed_net, (char *)data + FRAME_HEADER_FIELD_SIZE * 2, FRAME_HEADER_FIELD_SIZE);
97 memcpy(&size_net, (char *)data + FRAME_HEADER_FIELD_SIZE * 3, FRAME_HEADER_FIELD_SIZE);
98 *compressed = NET_TO_HOST_U32(compressed_net);
99 *data_size = NET_TO_HOST_U32(size_net);
100}
asciichat_error_t frame_validate_new(void *data, size_t len, bool *out_compressed, uint32_t *out_data_size)
asciichat_error_t frame_validate_legacy(size_t len, size_t expected_rgb_size)
void frame_extract_dimensions(const void *data, uint32_t *width, uint32_t *height)
void frame_extract_new_header(const void *data, uint32_t *compressed, uint32_t *data_size)
asciichat_error_t frame_check_size_overflow(size_t header_size, size_t data_size)
void format_bytes_pretty(size_t bytes, char *out, size_t out_capacity)
Definition util/format.c:10