Исправление уязвимости в форматированном выводе
This commit is contained in:
parent
9324f3f994
commit
6b15ba0f8a
229
kernel/tool.c
229
kernel/tool.c
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void tool_memcpy(void *dest, void *src, uint64_t n) {
|
void tool_memcpy(void *dest, void *src, uint64_t n) {
|
||||||
@ -44,130 +45,140 @@ uint64_t tool_starts_with(const char *str, const char *prefix) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Функция для переворачивания строки
|
||||||
|
void tool_reverse_str(char *str) {
|
||||||
|
int len = 0;
|
||||||
|
while (str[len] != '\0') { len++; }
|
||||||
|
|
||||||
|
int start = 0;
|
||||||
|
int end = len - 1;
|
||||||
|
|
||||||
|
while (start < end) {
|
||||||
|
char temp = str[start];
|
||||||
|
str[start] = str[end];
|
||||||
|
str[end] = temp;
|
||||||
|
start++;
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Преобразование целого числа "i" в системе счисления "base" в строку "buf"
|
||||||
|
void tool_int_to_str(int64_t i, uint8_t base, char *buf) {
|
||||||
|
bool negative = false;
|
||||||
|
|
||||||
|
// Проверяем, является ли число отрицательным
|
||||||
|
if (i < 0) {
|
||||||
|
negative = true;
|
||||||
|
i *= -1; // Если да, то умножаем на -1, чтобы сделать его положительным
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t index = 0;
|
||||||
|
// Деление с остатком для преобразования числа в нужную систему счисления
|
||||||
|
do {
|
||||||
|
int64_t remainder = i % base;
|
||||||
|
// Преобразовываем остаток в символ и добавляем его в строку
|
||||||
|
buf[index++] =
|
||||||
|
(remainder > 9)
|
||||||
|
? (remainder - 10) + 'A'
|
||||||
|
: remainder +
|
||||||
|
'0'; // Если остаток > 9, добавляем заглавную букву А
|
||||||
|
i /= base;
|
||||||
|
} while (i > 0);
|
||||||
|
|
||||||
|
// Если число было отрицательным, добавляем знак минуса в конец строки
|
||||||
|
if (negative) { buf[index++] = '-'; }
|
||||||
|
|
||||||
|
// Добавляем нулевой символ в конец строки, чтобы завершить ее
|
||||||
|
buf[index] = '\0';
|
||||||
|
|
||||||
|
// Переворачиваем строку, чтобы цифры были в правильном порядке
|
||||||
|
tool_reverse_str(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Преобразование неотрицательного целого числа "i" в системе счисления "base" в
|
||||||
|
// строку "buf"
|
||||||
|
void tool_uint_to_str(uint64_t i, uint8_t base, char *buf) {
|
||||||
|
uint64_t index = 0;
|
||||||
|
// Деление с остатком для преобразования числа в нужную систему счисления
|
||||||
|
do {
|
||||||
|
uint64_t remainder = i % base;
|
||||||
|
// Преобразовываем остаток в символ и добавляем его в строку
|
||||||
|
buf[index++] =
|
||||||
|
(remainder > 9)
|
||||||
|
? (remainder - 10) + 'A'
|
||||||
|
: remainder +
|
||||||
|
'0'; // Если остаток > 9, добавляем заглавную букву А
|
||||||
|
i /= base;
|
||||||
|
} while (i > 0);
|
||||||
|
|
||||||
|
// Добавляем нулевой символ в конец строки, чтобы завершить ее
|
||||||
|
buf[index] = '\0';
|
||||||
|
|
||||||
|
// Переворачиваем строку, чтобы цифры были в правильном порядке
|
||||||
|
tool_reverse_str(buf);
|
||||||
|
}
|
||||||
|
|
||||||
// Функция для форматированного вывода
|
// Функция для форматированного вывода
|
||||||
void tool_format(void (*putc)(char c), const char *format_string,
|
void tool_format(void (*putc)(char c), const char *format_string,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
while (*format_string != '\0') {
|
while (*format_string != '\0') {
|
||||||
if (*format_string == '%') {
|
if (*format_string == '%') {
|
||||||
|
char buf[48];
|
||||||
|
uint64_t point = 0;
|
||||||
|
const char *arg_s;
|
||||||
|
int64_t arg_d = 0;
|
||||||
|
uint64_t arg_u = 0;
|
||||||
format_string++;
|
format_string++;
|
||||||
|
|
||||||
if (*format_string == '\0') {
|
if (*format_string == '\0') {
|
||||||
break; // Неожиданный конец строки формата
|
break; // Неожиданный конец строки формата
|
||||||
}
|
}
|
||||||
if (*format_string == '%') {
|
|
||||||
putc('%'); // Вывод одного символа '%'
|
|
||||||
} else if (*format_string == 'd') {
|
|
||||||
int64_t arg = va_arg(args, int64_t);
|
|
||||||
// Преобразование целочисленного аргумента в строку и вывод
|
|
||||||
// каждого символа
|
|
||||||
if (arg < 0) {
|
|
||||||
putc('-');
|
|
||||||
arg = -arg;
|
|
||||||
}
|
|
||||||
if (arg == 0) {
|
|
||||||
putc('0');
|
|
||||||
} else {
|
|
||||||
char buffer[10]; // Предполагаем, что максимальное число из
|
|
||||||
// 10 цифр
|
|
||||||
int64_t i = 0;
|
|
||||||
|
|
||||||
while (arg > 0) {
|
switch (*format_string) {
|
||||||
buffer[i++] = '0' + (arg % 10);
|
case '%': putc('%'); break;
|
||||||
arg /= 10;
|
case 'c': putc(va_arg(args, int)); break;
|
||||||
|
case 's':
|
||||||
|
arg_s = va_arg(args, const char *);
|
||||||
|
// Вывод каждого символа строки
|
||||||
|
while (*arg_s != '\0') {
|
||||||
|
putc(*arg_s);
|
||||||
|
arg_s++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
arg_d = va_arg(args, int64_t);
|
||||||
|
tool_int_to_str(arg_d, 10, buf);
|
||||||
|
while (buf[point] != '\0') {
|
||||||
|
putc(buf[point]);
|
||||||
|
point++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i > 0) { putc(buffer[--i]); }
|
break;
|
||||||
}
|
case 'u':
|
||||||
} else if (*format_string == 's') {
|
arg_u = va_arg(args, uint64_t);
|
||||||
const char *arg = va_arg(args, const char *);
|
tool_uint_to_str(arg_u, 10, buf);
|
||||||
// Вывод каждого символа строки
|
while (buf[point] != '\0') {
|
||||||
while (*arg != '\0') {
|
putc(buf[point]);
|
||||||
putc(*arg);
|
point++;
|
||||||
arg++;
|
|
||||||
}
|
|
||||||
} else if (*format_string == 'u') {
|
|
||||||
uint64_t arg = va_arg(args, uint64_t);
|
|
||||||
// Преобразование беззнакового целочисленного аргумента в строку
|
|
||||||
// и вывод каждого символа
|
|
||||||
if (arg == 0) {
|
|
||||||
putc('0');
|
|
||||||
} else {
|
|
||||||
char buffer[32]; // Предполагаем, что максимальное число из
|
|
||||||
// 10 цифр
|
|
||||||
int64_t i = 0;
|
|
||||||
|
|
||||||
while (arg > 0) {
|
|
||||||
buffer[i++] = '0' + (arg % 10);
|
|
||||||
arg /= 10;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
while (i > 0) { putc(buffer[--i]); }
|
case 'x':
|
||||||
}
|
arg_u = va_arg(args, uint64_t);
|
||||||
} else if (*format_string == 'x') {
|
tool_uint_to_str(arg_u, 16, buf);
|
||||||
uint64_t arg = va_arg(args, uint64_t);
|
while (buf[point] != '\0') {
|
||||||
// Преобразование беззнакового целочисленного аргумента в
|
putc(buf[point]);
|
||||||
// шестнадцатеричную строку и вывод каждого символа
|
point++;
|
||||||
if (arg == 0) {
|
|
||||||
putc('0');
|
|
||||||
} else {
|
|
||||||
char buffer[32]; // Предполагаем, что максимальное число из
|
|
||||||
// 8 символов
|
|
||||||
int64_t i = 0;
|
|
||||||
|
|
||||||
while (arg > 0) {
|
|
||||||
int64_t rem = arg % 16;
|
|
||||||
if (rem < 10) {
|
|
||||||
buffer[i++] = '0' + rem;
|
|
||||||
} else {
|
|
||||||
buffer[i++] = 'A' + (rem - 10);
|
|
||||||
}
|
|
||||||
arg /= 16;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
while (i > 0) { putc(buffer[--i]); }
|
case 'l':
|
||||||
}
|
arg_u = va_arg(args, uint64_t);
|
||||||
} else if (*format_string == 'c') {
|
tool_uint_to_str(arg_u, 16, buf);
|
||||||
char arg = va_arg(args, int);
|
while (buf[point] != '\0') {
|
||||||
// Вывод символа
|
putc(buf[point]);
|
||||||
putc(arg);
|
point++;
|
||||||
} else if (*format_string == 'o') {
|
|
||||||
uint64_t arg = va_arg(args, uint64_t);
|
|
||||||
// Преобразование беззнакового целочисленного аргумента в
|
|
||||||
// восьмеричную строку и вывод каждого символа
|
|
||||||
if (arg == 0) {
|
|
||||||
putc('0');
|
|
||||||
} else {
|
|
||||||
char buffer[12]; // Предполагаем, что максимальное число из
|
|
||||||
// 11 символов
|
|
||||||
int64_t i = 0;
|
|
||||||
|
|
||||||
while (arg > 0) {
|
|
||||||
buffer[i++] = '0' + (arg % 8);
|
|
||||||
arg /= 8;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
while (i > 0) { putc(buffer[--i]); }
|
default: putc('?'); break;
|
||||||
}
|
|
||||||
} else if (*format_string == 'b') {
|
|
||||||
uint64_t arg = va_arg(args, uint64_t);
|
|
||||||
// Преобразование беззнакового целочисленного аргумента в
|
|
||||||
// двоичную строку и вывод каждого символа
|
|
||||||
if (arg == 0) {
|
|
||||||
putc('0');
|
|
||||||
} else {
|
|
||||||
char buffer[33]; // Предполагаем, что максимальное число из
|
|
||||||
// 32 символа
|
|
||||||
int64_t i = 0;
|
|
||||||
|
|
||||||
while (arg > 0) {
|
|
||||||
buffer[i++] = '0' + (arg % 2);
|
|
||||||
arg /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i > 0) { putc(buffer[--i]); }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Неподдерживаемый спецификатор формата
|
|
||||||
putc('?');
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
putc(*format_string);
|
putc(*format_string);
|
||||||
|
Loading…
Reference in New Issue
Block a user