1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
const std = @import("std");
const eql = std.mem.eql;
pub fn escape(alloc: std.mem.Allocator, v: []const u8) ![]const u8 {
var acc = try std.ArrayList(u8).initCapacity(alloc, v.len);
errdefer acc.deinit(alloc);
const view = try std.unicode.Utf8View.init(v);
var iter = view.iterator();
while (iter.nextCodepointSlice()) |rune| {
if (eql(u8, rune, "&")) {
try acc.appendSlice(alloc, "&");
} else if (eql(u8, rune, "'")) {
try acc.appendSlice(alloc, "'");
} else if (eql(u8, rune, "<")) {
try acc.appendSlice(alloc, "<");
} else if (eql(u8, rune, ">")) {
try acc.appendSlice(alloc, ">");
} else if (eql(u8, rune, "\"")) {
try acc.appendSlice(alloc, """);
} else {
try acc.appendSlice(alloc, rune);
}
}
return acc.toOwnedSlice(alloc);
}
fn doTest(alloc: std.mem.Allocator, el: []const u8, exp: []const u8) !void {
const got = try escape(alloc, el);
defer alloc.free(got);
std.testing.expect(eql(u8, got, exp)) catch |err| {
std.debug.print("{s}\n", .{got});
return err;
};
}
test "escaping html" {
const alloc = std.testing.allocator;
try doTest(alloc, "hello world", "hello world");
try doTest(alloc, "hello&world", "hello&world");
try doTest(alloc, "hello'world", "hello'world");
try doTest(alloc, "hello<world", "hello<world");
try doTest(alloc, "hello>world", "hello>world");
try doTest(alloc, "hello\"world", "hello"world");
}
|