Let's scrutinize some vibe code that promises to change the world or whatever. We'll review and analyze this code using static analysis.
Vib-OS–World's First Vibecoded AI Operating System
A YouTuber known as Tirimid reviewed Vib-OS—an OS written entirely using AI. As a result, he discovered that the OS couldn't even run DOOM or connect to the internet. I decided to take a look as well. So, I looked through the code and ran the PVS-Studio static analyzer.
The project is quite small, actually. An "OS" is just a fancy term here. Let's calculate the size. First, I removed third-party elements, such as files that didn't contain "vibeos," "vibcode," or "vib-os". Next, I removed resources represented as arrays:
unsigned char doom1_wad[] = {
0x49, 0x57, 0x41, 0x44, 0xf0, 0x04, 0x00, 0x00, 0xb4, 0xb7, 0x3f, 0x00,
0x00, 0x00, 0x00, 0x1f, 0x17, 0x0b, 0x17, 0x0f, 0x07, 0x4b, 0x4b, 0x4b,
0xff, 0xff, 0xff, 0x1b, 0x1b, 0x1b, 0x13, 0x13, 0x13, 0x0b, 0x0b, 0x0b,
....
I ended up with about 110 files containing 35,000 lines of C code. This isn't much, and I didn't think there would be anything worth writing about there at all. However, I quickly found flaws and cringe-worthy moments that I wanted to share.
Verbosity
The first thing you notice is how bloated the code is. It takes up so much space, and sometimes you can't even make sense of it. I'd rather use the sprintf function than write the code this way:
char seq[32];
int s = 0;
seq[s++] = ':';
seq[s++] = ' ';
seq[s++] = 'i';
seq[s++] = 'c';
seq[s++] = 'm';
seq[s++] = 'p';
seq[s++] = '_';
seq[s++] = 's';
seq[s++] = 'e';
seq[s++] = 'q';
seq[s++] = '=';
seq[s++] = '0' + i;
seq[s++] = ' ';
seq[s++] = 't';
seq[s++] = 't';
seq[s++] = 'l';
seq[s++] = '=';
seq[s++] = '6';
seq[s++] = '4';
seq[s++] = ' ';
seq[s++] = 't';
seq[s++] = 'i';
seq[s++] = 'm';
seq[s++] = 'e';
seq[s++] = '=';
/* Random-ish time 10-50ms */
int time_ms = 15 + (i * 7) % 30;
seq[s++] = '0' + (time_ms / 10);
seq[s++] = '0' + (time_ms % 10);
seq[s++] = ' ';
seq[s++] = 'm';
seq[s++] = 's';
seq[s++] = '\n';
seq[s] = '\0';
Here's another example. The following functions are implemented in doom_libc.c:
int isdigit(int c) { return c >= '0' && c <= '9'; }
int isupper(int c) { return c >= 'A' && c <= 'Z'; }
int islower(int c) { return c >= 'a' && c <= 'z'; }
However, further down in the same file, characters are sometimes checked directly without using these functions:
if (*s >= '0' && *s <= '9') digit = *s - '0';
else if (*s >= 'a' && *s <= 'z') digit = *s - 'a' + 10;
else if (*s >= 'A' && *s <= 'Z') digit = *s - 'A' + 10;
I Like to Move It, Move It
Similar blocks of code for copying byte arrays are everywhere—they just beg to be replaced with something like memcpy, strcpy, and similar functions. I even came across four separate implementations of string-copying functions that do exactly the same thing.
static void str_copy(char *dst, const char *src, int max) {
int i = 0;
while (src[i] && i < max - 1) {
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}
static void str_cpy(char *dst, const char *src, int max) {
int i = 0;
while (src[i] && i < max - 1) {
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}
static void strcpy_safe(char *dst, const char *src, size_t max) {
size_t i = 0;
while (src[i] && i < max - 1) {
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}
static inline char *strncpy_safe(char *dst, const char *src, size_t n) {
size_t i;
for (i = 0; i < n - 1 && src[i]; i++) {
dst[i] = src[i];
}
dst[i] = '\0';
return dst;
}
Different buffers are constantly being "manually" copied in various fragments:
uint8_t *src = buf + offset_in_block;
uint8_t *dst = (uint8_t *)inode;
for (size_t i = 0; i < sizeof(struct ext4_inode); i++) {
dst[i] = src[i];
}
uint8_t *src = sb_buf;
uint8_t *dst = (uint8_t *)&fs->sb;
for (size_t i = 0; i < sizeof(struct ext4_superblock); i++) {
dst[i] = src[i];
}
uint8_t *src = (uint8_t *)ptr;
uint8_t *dst = (uint8_t *)new_ptr;
for (size_t i = 0; i < old_size; i++) {
dst[i] = src[i];
}
We can replace all these four-liners with memcpy or, at the very least, with a single well-written copy function. Especially since the code occasionally tries to copy buffers with some optimization in mind:
size_t i = 0;
size_t fast_count = count64 & ~7UL;
for (; i < fast_count; i += 8) {
dst[i] = src[i];
dst[i + 1] = src[i + 1];
dst[i + 2] = src[i + 2];
dst[i + 3] = src[i + 3];
dst[i + 4] = src[i + 4];
dst[i + 5] = src[i + 5];
dst[i + 6] = src[i + 6];
dst[i + 7] = src[i + 7];
}
for (; i < count64; i++) {
dst[i] = src[i];
}
It seems like the AI never gets tired of writing code and really loves copying and pasting data back and forth. For example, the bt_set_local_name function simply copies a string to a 248-byte buffer and passes it on to hci_send_cmd.
int bt_set_local_name(const char *name)
{
uint8_t params[248] = {0};
int len = 0;
while (name[len] && len < 247) {
params[len] = name[len];
len++;
}
return hci_send_cmd(HCI_OP_WRITE_LOCAL_NAME, params, 248);
}
Let's see what happens to the string next:
static int hci_send_cmd(uint16_t opcode, void *params, uint8_t plen)
{
uint8_t buf[256];
buf[0] = HCI_COMMAND_PKT;
struct hci_command_hdr *hdr = (struct hci_command_hdr *)&buf[1];
hdr->opcode = opcode;
hdr->plen = plen;
if (plen > 0 && params) {
for (int i = 0; i < plen; i++) {
buf[4 + i] = ((uint8_t *)params)[i];
}
}
/* TODO: Send via USB bulk endpoint */
printk(KERN_DEBUG "BT: Send cmd opcode=0x%04x len=%d\n", opcode, plen);
return 0;
}
A new buffer is created using a special header and the passed string. The buffer isn't used further, but that's not the point. The purpose of the intermediate buffer in bt_set_local_name is unclear. We can shorten the code while improving its performance.
Bugs
What about bugs? Reviewing some static analyzer warnings can be difficult due to long functions and bloated code. In some cases, errors are obvious, though.
Pointless checks
void term_execute_command(struct terminal *term, const char *cmd) {
....
/* Built-in commands */
if (str_starts_with(cmd, "clear")) {
....
} else if (str_starts_with(cmd, "help")) {
....
} else if (str_starts_with(cmd, "ping ")) { // <=
term_puts(term, "Pinging ");
term_puts(term, cmd + 5);
term_puts(term, "...\n");
char *ip_str = (char *)cmd + 5;
uint32_t ip = 0;
int octet = 0;
int shift = 24;
....
} else if (str_starts_with(cmd, "browser")) {
....
}
else if (str_starts_with(cmd, "ping ")) { // <=
const char *host = cmd + 5;
while (*host == ' ')
host++;
term_puts(term, "PING ");
term_puts(term, host);
term_puts(term, " (10.0.2.15): 56 data bytes\n");
....
}
....
}
PVS-Studio warning: V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 697, 1029. terminal.c 697
The check to ensure that the string begins with ping is performed twice. They use different handlers, so something clearly went wrong here.
Here's a similar bug:
static void draw_window(struct window *win) {
....
if (win->title[0] == 'C' && win->title[1] == 'a' && win->title[2] == 'l') {
....
/* Clock window */
else if (win->title[0] == 'C' && win->title[1] == 'l' &&
win->title[2] == 'o') {
int center_x = content_x + content_w / 2;
int center_y = content_y + content_h / 2;
int radius = 60;
char *ip_str = (char *)cmd + 5;
uint32_t ip = 0;
int octet = 0;
int shift = 24;
....
}
/* Game window */
else if (win->title[0] == 'G' && win->title[1] == 'a' &&
win->title[2] == 'm') {
....
/* Clock */
else if (win->title[0] == 'C' && win->title[1] == 'l' &&
win->title[2] == 'o') {
int cx = content_x + content_w / 2;
int cy = content_y + content_h / 2;
int r = (content_w < content_h ? content_w : content_h) / 2 - 16;
/* Draw Clock Face */
gui_draw_circle(cx, cy, r, 0xF0F0F0, true); /* Face */
gui_draw_circle(cx, cy, r, 0x808080, false); /* Outline */
gui_draw_circle(cx, cy, 3, 0x000000, true); /* Center dot */
....
}
....
}
PVS-Studio warning: V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 1962, 2335. window.c 1962
The check for the /* Clock window */ and /* Clock */ code blocks is identical:
if (win->title[0] == 'C' && win->title[1] == 'l' && win->title[2] == 'o')
So, this is an error—unreachable code.
Code duplication
There are duplicate code blocks:
static void fm_on_mouse(struct window *win, int x, int y, int buttons) {
....
/* Initialize dimensions */
fctx.slot_w = 80;
fctx.slot_h = 70;
fctx.win_w = win->width - 40; /* Match wrapped logic in render callback */
fctx.slot_w = 80;
fctx.slot_h = 70;
fctx.win_w = win->width - 40;
....
}
One of PVS-Studio warnings: V519 The 'fctx.slot_w' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 1242, 1245. window.c 1245
Here's another example:
static void draw_menu_bar(void) {
....
/* WiFi Icon (Static Connected) */
{
int wx = primary_display.width - 86;
int wy = 12;
/* Draw arcs using simple lines/pixels */
/* Center dot */
gui_draw_rect(wx, wy + 6, 2, 2, 0xFFFFFF);
/* Middle arc */
gui_draw_line(wx - 3, wy + 3, wx, wy, 0xFFFFFF);
gui_draw_line(wx, wy, wx + 3, wy + 3, 0xFFFFFF);
/* Top arc */
gui_draw_line(wx - 6, wy, wx, wy - 3, 0xFFFFFF);
gui_draw_line(wx, wy - 3, wx + 6, wy, 0xFFFFFF);
}
/* WiFi Icon (Static Connected) */
{
int wx = primary_display.width - 86;
int wy = 12;
/* Draw arcs using simple lines/pixels */
/* Center dot */
gui_draw_rect(wx, wy + 6, 2, 2, 0xFFFFFF);
/* Middle arc */
gui_draw_line(wx - 3, wy + 3, wx, wy, 0xFFFFFF);
gui_draw_line(wx, wy, wx + 3, wy + 3, 0xFFFFFF);
/* Top arc */
gui_draw_line(wx - 6, wy, wx, wy - 3, 0xFFFFFF);
gui_draw_line(wx, wy - 3, wx + 6, wy, 0xFFFFFF);
}
....
}
PVS-Studio warning: V760 Two identical blocks of text were found. The second block begins from line 2558. window.c 2543
The following fragment shows that not only humans can make typos:
static void draw_window(struct window *win) {
....
if (btn_char == '/' || btn_char == '*' || btn_char == '-' ||
btn_char == '+' || btn_char == '=') {
/* Orange operator buttons */
bg = 0xFF9F0A;
fg = 0xFFFFFF;
} else if (btn_char == 'C' || btn_char == '+' || btn_char == '%') {
/* Light gray function buttons */
bg = 0xA5A5A5;
fg = 0x000000;
} else {
....
}
PVS-Studio warning: V560 A part of conditional expression is always false: btn_char == '+'. window.c 1713
The condition here is incorrect. Perhaps it should be different. There's no point in checking the variable again to see whether it equals +.
Data alignment
Last but not least, let's take a look at dangerous data alignment:
/* Optimized memcpy for scanlines */
static inline void fast_memcpy_line(uint32_t *dst, uint32_t *src, int width) {
/* Use 64-bit copies for better performance */
uint64_t *d64 = (uint64_t *)dst;
uint64_t *s64 = (uint64_t *)src;
int count = width / 2;
for (int i = 0; i < count; i++) {
d64[i] = s64[i];
}
/* Handle odd pixel */
if (width & 1) {
dst[width - 1] = src[width - 1];
}
}
PVS-Studio warnings:
- V1032 The pointer 'dst' is cast to a more strictly aligned pointer type. window.c 3108
- V1032 The pointer 'src' is cast to a more strictly aligned pointer type. window.c 3109
This code may work, but it's quite dangerous. If the input pointers aren't aligned on a 64-bit boundary, undefined behavior will occur.
I can't say for sure whether that will happen or not. Honestly, I couldn't be bothered to figure out how the code that calls the fast_memcpy_line function would work, or what the alignment would be. Here's the code:
static void blit_region(int x, int y, int w, int h) {
if (!primary_display.backbuffer || !primary_display.framebuffer)
return;
/* Clip to screen bounds */
if (x < 0) {
w += x;
x = 0;
}
if (y < 0) {
h += y;
y = 0;
}
if (x + w > (int)primary_display.width)
w = primary_display.width - x;
if (y + h > (int)primary_display.height)
h = primary_display.height - y;
if (w <= 0 || h <= 0)
return;
int pitch_pixels = primary_display.pitch / 4;
for (int row = y; row < y + h; row++) {
uint32_t *src = primary_display.backbuffer + row * pitch_pixels + x;
uint32_t *dst = primary_display.framebuffer + row * pitch_pixels + x;
fast_memcpy_line(dst, src, w);
}
}
In any case, the code looks really dangerous and vulnerable to malicious use. I'd advise against writing code like that. My colleague recently explored the topic of data alignment and the associated errors in her article, "Silent foe or quiet ally: Brief guide to alignment in C++": Part 1, Part 2.
Conclusion
That's all for now. If you know of any open-source vibe coding projects, please share the links in the comments. We'll check out some more interesting stuff.
Here's a boring summary: whether you write code yourself or generate it using AI, to achieve high quality and reliability, make sure to perform code reviews, use PVS-Studio analyzer, and follow other SSDLC practices.

Top comments (0)