130 lines
4.2 KiB
Zig
130 lines
4.2 KiB
Zig
const std = @import("std");
|
|
const lib = @import("../lib.zig");
|
|
const paste = @import("../../input/paste.zig");
|
|
const Result = @import("result.zig").Result;
|
|
|
|
pub fn is_safe(data: ?[*]const u8, len: usize) callconv(lib.calling_conv) bool {
|
|
const slice: []const u8 = if (data) |v| v[0..len] else &.{};
|
|
return paste.isSafe(slice);
|
|
}
|
|
|
|
pub fn encode(
|
|
data: ?[*]u8,
|
|
data_len: usize,
|
|
bracketed: bool,
|
|
out_: ?[*]u8,
|
|
out_len: usize,
|
|
out_written: *usize,
|
|
) callconv(lib.calling_conv) Result {
|
|
const slice: []u8 = if (data) |v| v[0..data_len] else &.{};
|
|
const result = paste.encode(slice, .{ .bracketed = bracketed });
|
|
|
|
const total = result[0].len + result[1].len + result[2].len;
|
|
out_written.* = total;
|
|
|
|
const out: []u8 = if (out_) |o| o[0..out_len] else &.{};
|
|
if (out.len < total) return .out_of_space;
|
|
|
|
var offset: usize = 0;
|
|
for (result) |segment| {
|
|
@memcpy(out[offset..][0..segment.len], segment);
|
|
offset += segment.len;
|
|
}
|
|
|
|
return .success;
|
|
}
|
|
|
|
test "encode bracketed" {
|
|
const testing = std.testing;
|
|
const input = try testing.allocator.dupe(u8, "hello");
|
|
defer testing.allocator.free(input);
|
|
var buf: [64]u8 = undefined;
|
|
var written: usize = 0;
|
|
const result = encode(input.ptr, input.len, true, &buf, buf.len, &written);
|
|
try testing.expectEqual(.success, result);
|
|
try testing.expectEqualStrings("\x1b[200~hello\x1b[201~", buf[0..written]);
|
|
}
|
|
|
|
test "encode unbracketed no newlines" {
|
|
const testing = std.testing;
|
|
const input = try testing.allocator.dupe(u8, "hello");
|
|
defer testing.allocator.free(input);
|
|
var buf: [64]u8 = undefined;
|
|
var written: usize = 0;
|
|
const result = encode(input.ptr, input.len, false, &buf, buf.len, &written);
|
|
try testing.expectEqual(.success, result);
|
|
try testing.expectEqualStrings("hello", buf[0..written]);
|
|
}
|
|
|
|
test "encode unbracketed newlines" {
|
|
const testing = std.testing;
|
|
const input = try testing.allocator.dupe(u8, "hello\nworld");
|
|
defer testing.allocator.free(input);
|
|
var buf: [64]u8 = undefined;
|
|
var written: usize = 0;
|
|
const result = encode(input.ptr, input.len, false, &buf, buf.len, &written);
|
|
try testing.expectEqual(.success, result);
|
|
try testing.expectEqualStrings("hello\rworld", buf[0..written]);
|
|
}
|
|
|
|
test "encode strip unsafe bytes" {
|
|
const testing = std.testing;
|
|
const input = try testing.allocator.dupe(u8, "hel\x1blo\x00world");
|
|
defer testing.allocator.free(input);
|
|
var buf: [64]u8 = undefined;
|
|
var written: usize = 0;
|
|
const result = encode(input.ptr, input.len, true, &buf, buf.len, &written);
|
|
try testing.expectEqual(.success, result);
|
|
try testing.expectEqualStrings("\x1b[200~hel lo world\x1b[201~", buf[0..written]);
|
|
}
|
|
|
|
test "encode with insufficient buffer" {
|
|
const testing = std.testing;
|
|
const input = try testing.allocator.dupe(u8, "hello");
|
|
defer testing.allocator.free(input);
|
|
var buf: [1]u8 = undefined;
|
|
var written: usize = 0;
|
|
const result = encode(input.ptr, input.len, true, &buf, buf.len, &written);
|
|
try testing.expectEqual(.out_of_space, result);
|
|
try testing.expectEqual(17, written);
|
|
}
|
|
|
|
test "encode with null buffer" {
|
|
const testing = std.testing;
|
|
const input = try testing.allocator.dupe(u8, "hello");
|
|
defer testing.allocator.free(input);
|
|
var written: usize = 0;
|
|
const result = encode(input.ptr, input.len, true, null, 0, &written);
|
|
try testing.expectEqual(.out_of_space, result);
|
|
try testing.expectEqual(17, written);
|
|
}
|
|
|
|
test "is_safe with safe data" {
|
|
const testing = std.testing;
|
|
const safe = "hello world";
|
|
try testing.expect(is_safe(safe.ptr, safe.len));
|
|
}
|
|
|
|
test "is_safe with newline" {
|
|
const testing = std.testing;
|
|
const unsafe = "hello\nworld";
|
|
try testing.expect(!is_safe(unsafe.ptr, unsafe.len));
|
|
}
|
|
|
|
test "is_safe with bracketed paste end" {
|
|
const testing = std.testing;
|
|
const unsafe = "hello\x1b[201~world";
|
|
try testing.expect(!is_safe(unsafe.ptr, unsafe.len));
|
|
}
|
|
|
|
test "is_safe with empty data" {
|
|
const testing = std.testing;
|
|
const empty = "";
|
|
try testing.expect(is_safe(empty.ptr, 0));
|
|
}
|
|
|
|
test "is_safe with null empty data" {
|
|
const testing = std.testing;
|
|
try testing.expect(is_safe(null, 0));
|
|
}
|