diff --git a/bulb/bulb.ha b/bulb/bulb.ha index d24c548..ed0f4c8 100644 --- a/bulb/bulb.ha +++ b/bulb/bulb.ha @@ -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);