Validate board names to prevent goofy shenanigans

This commit is contained in:
Sasha Koshka 2024-10-09 21:01:53 -04:00
parent 945cdf5177
commit c7cafca8e7

View File

@ -10,15 +10,18 @@ let bulb_path: []str = [];
@fini fn bulb_path() void = free(bulb_path);
export type no_such_board = !void;
export type error = (io::error | fs::error | no_such_board);
export type invalid_board = !void;
export type error = (io::error | fs::error | no_such_board | invalid_board);
export fn strerror(err: error) str = match(err) {
case no_such_board => return "No such board";
case no_such_board => return "No such board";
case invalid_board => return "Invalid board name";
case let err: fs::error => return fs::strerror(err);
case let err: io::error => return io::strerror(err);
};
export fn read(board: str, number: int) (void | error) = {
validate_board_name(board)?;
let location = look_up_board(board)?;
let file = os::open(location)?;
defer io::close(file)!;
@ -27,6 +30,7 @@ export fn read(board: str, number: int) (void | error) = {
};
export fn post(board: str, user_name: (str | void), message: str) (void | error) = {
validate_board_name(board)?;
let location = look_up_board(board)?;
let file = os::open(location, fs::flag::APPEND | fs::flag::WRONLY)?;
defer io::close(file)!;
@ -42,7 +46,8 @@ export fn list() (void | error) = {
for (let directory .. bulb_path) list_boards_in(directory)?;
};
export fn look_up_board(board: str) (str | no_such_board) = {
export fn look_up_board(board: str) (str | no_such_board | invalid_board) = {
validate_board_name(board)?;
static let buf = path::buffer { ... };
for (let directory .. bulb_path) {
let location = path::set(&buf, directory, board)!;
@ -54,6 +59,21 @@ export fn look_up_board(board: str) (str | no_such_board) = {
return no_such_board;
};
export fn validate_board_name(board: str) (void | invalid_board) = {
let iter = strings::iter(board);
for (true) match (strings::next(&iter)) {
case let run: rune =>
if (
run: int == '/' ||
run: int == '.' ||
run: int == '\\' ||
run: int == ':') {
return invalid_board;
};
case done => return void;
};
};
fn list_boards_in(directory: str) (void | fs::error) = {
let entries = os::readdir(directory)?;
defer fs::dirents_free(entries);