mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std: Add more error checking in hexToBytes
Prevent the function from turning into an endless loop that may or may not perform OOB accesses.
This commit is contained in:
parent
4272f07f66
commit
057bf1afc9
@ -207,7 +207,7 @@ pub const Ed25519 = struct {
|
||||
|
||||
test "ed25519 key pair creation" {
|
||||
var seed: [32]u8 = undefined;
|
||||
try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
_ = try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
const key_pair = try Ed25519.KeyPair.create(seed);
|
||||
var buf: [256]u8 = undefined;
|
||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{key_pair.secret_key}), "8052030376D47112BE7F73ED7A019293DD12AD910B654455798B4667D73DE1662D6F7455D97B4A3A10D7293909D1A4F2058CB9A370E43FA8154BB280DB839083");
|
||||
@ -216,7 +216,7 @@ test "ed25519 key pair creation" {
|
||||
|
||||
test "ed25519 signature" {
|
||||
var seed: [32]u8 = undefined;
|
||||
try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
_ = try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
const key_pair = try Ed25519.KeyPair.create(seed);
|
||||
|
||||
const sig = try Ed25519.sign("test", key_pair, null);
|
||||
@ -339,11 +339,11 @@ test "ed25519 test vectors" {
|
||||
};
|
||||
for (entries) |entry, i| {
|
||||
var msg: [entry.msg_hex.len / 2]u8 = undefined;
|
||||
try fmt.hexToBytes(&msg, entry.msg_hex);
|
||||
_ = try fmt.hexToBytes(&msg, entry.msg_hex);
|
||||
var public_key: [32]u8 = undefined;
|
||||
try fmt.hexToBytes(&public_key, entry.public_key_hex);
|
||||
_ = try fmt.hexToBytes(&public_key, entry.public_key_hex);
|
||||
var sig: [64]u8 = undefined;
|
||||
try fmt.hexToBytes(&sig, entry.sig_hex);
|
||||
_ = try fmt.hexToBytes(&sig, entry.sig_hex);
|
||||
if (entry.expected) |error_type| {
|
||||
std.testing.expectError(error_type, Ed25519.verify(sig, &msg, public_key));
|
||||
} else {
|
||||
|
||||
@ -173,7 +173,7 @@ test "ristretto255" {
|
||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{p.toBytes()}), "E2F2AE0A6ABC4E71A884A961C500515F58E30B6AA582DD8DB6A65945E08D2D76");
|
||||
|
||||
var r: [Ristretto255.encoded_length]u8 = undefined;
|
||||
try fmt.hexToBytes(r[0..], "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919");
|
||||
_ = try fmt.hexToBytes(r[0..], "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919");
|
||||
var q = try Ristretto255.fromBytes(r);
|
||||
q = q.dbl().add(p);
|
||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{q.toBytes()}), "E882B131016B52C1D3337080187CF768423EFCCBB517BB495AB812C4160FF44E");
|
||||
|
||||
@ -85,8 +85,8 @@ const htest = @import("../test.zig");
|
||||
test "x25519 public key calculation from secret key" {
|
||||
var sk: [32]u8 = undefined;
|
||||
var pk_expected: [32]u8 = undefined;
|
||||
try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50");
|
||||
_ = try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
_ = try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50");
|
||||
const pk_calculated = try X25519.recoverPublicKey(sk);
|
||||
std.testing.expectEqual(pk_calculated, pk_expected);
|
||||
}
|
||||
|
||||
@ -122,11 +122,11 @@ test "expand 128-bit key" {
|
||||
var exp: [16]u8 = undefined;
|
||||
|
||||
for (enc.key_schedule.round_keys) |round_key, i| {
|
||||
try std.fmt.hexToBytes(&exp, exp_enc[i]);
|
||||
_ = try std.fmt.hexToBytes(&exp, exp_enc[i]);
|
||||
testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
|
||||
}
|
||||
for (enc.key_schedule.round_keys) |round_key, i| {
|
||||
try std.fmt.hexToBytes(&exp, exp_dec[i]);
|
||||
_ = try std.fmt.hexToBytes(&exp, exp_dec[i]);
|
||||
testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
|
||||
}
|
||||
}
|
||||
@ -144,11 +144,11 @@ test "expand 256-bit key" {
|
||||
var exp: [16]u8 = undefined;
|
||||
|
||||
for (enc.key_schedule.round_keys) |round_key, i| {
|
||||
try std.fmt.hexToBytes(&exp, exp_enc[i]);
|
||||
_ = try std.fmt.hexToBytes(&exp, exp_enc[i]);
|
||||
testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
|
||||
}
|
||||
for (dec.key_schedule.round_keys) |round_key, i| {
|
||||
try std.fmt.hexToBytes(&exp, exp_dec[i]);
|
||||
_ = try std.fmt.hexToBytes(&exp, exp_dec[i]);
|
||||
testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
|
||||
}
|
||||
}
|
||||
|
||||
@ -663,7 +663,7 @@ fn testBlake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void {
|
||||
|
||||
// Compare to expected value
|
||||
var expected_bytes: [expected_hex.len / 2]u8 = undefined;
|
||||
fmt.hexToBytes(expected_bytes[0..], expected_hex[0..]) catch unreachable;
|
||||
_ = fmt.hexToBytes(expected_bytes[0..], expected_hex[0..]) catch unreachable;
|
||||
testing.expectEqual(actual_bytes, expected_bytes);
|
||||
|
||||
// Restore initial state
|
||||
|
||||
@ -270,7 +270,7 @@ pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void {
|
||||
test "hash" {
|
||||
// a test vector (30) from NIST KAT submission.
|
||||
var msg: [58 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
|
||||
_ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
|
||||
var md: [32]u8 = undefined;
|
||||
hash(&md, &msg, .{});
|
||||
htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md);
|
||||
@ -278,7 +278,7 @@ test "hash" {
|
||||
|
||||
test "hash test vector 17" {
|
||||
var msg: [32 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F");
|
||||
_ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F");
|
||||
var md: [32]u8 = undefined;
|
||||
hash(&md, &msg, .{});
|
||||
htest.assertEqual("404C130AF1B9023A7908200919F690FFBB756D5176E056FFDE320016A37C7282", &md);
|
||||
@ -286,7 +286,7 @@ test "hash test vector 17" {
|
||||
|
||||
test "hash test vector 33" {
|
||||
var msg: [32]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
_ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
var md: [32]u8 = undefined;
|
||||
hash(&md, &msg, .{});
|
||||
htest.assertEqual("A8F4FA28708BDA7EFB4C1914CA4AFA9E475B82D588D36504F87DBB0ED9AB3C4B", &md);
|
||||
@ -436,9 +436,9 @@ pub const Aead = struct {
|
||||
|
||||
test "cipher" {
|
||||
var key: [32]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&key, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
_ = try std.fmt.hexToBytes(&key, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
var nonce: [16]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&nonce, "000102030405060708090A0B0C0D0E0F");
|
||||
_ = try std.fmt.hexToBytes(&nonce, "000102030405060708090A0B0C0D0E0F");
|
||||
{ // test vector (1) from NIST KAT submission.
|
||||
const ad: [0]u8 = undefined;
|
||||
const pt: [0]u8 = undefined;
|
||||
@ -456,7 +456,7 @@ test "cipher" {
|
||||
{ // test vector (34) from NIST KAT submission.
|
||||
const ad: [0]u8 = undefined;
|
||||
var pt: [2 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&pt, "00");
|
||||
_ = try std.fmt.hexToBytes(&pt, "00");
|
||||
|
||||
var ct: [pt.len]u8 = undefined;
|
||||
var tag: [16]u8 = undefined;
|
||||
@ -470,9 +470,9 @@ test "cipher" {
|
||||
}
|
||||
{ // test vector (106) from NIST KAT submission.
|
||||
var ad: [12 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&ad, "000102030405");
|
||||
_ = try std.fmt.hexToBytes(&ad, "000102030405");
|
||||
var pt: [6 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&pt, "000102");
|
||||
_ = try std.fmt.hexToBytes(&pt, "000102");
|
||||
|
||||
var ct: [pt.len]u8 = undefined;
|
||||
var tag: [16]u8 = undefined;
|
||||
@ -486,9 +486,9 @@ test "cipher" {
|
||||
}
|
||||
{ // test vector (790) from NIST KAT submission.
|
||||
var ad: [60 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&ad, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D");
|
||||
_ = try std.fmt.hexToBytes(&ad, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D");
|
||||
var pt: [46 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F10111213141516");
|
||||
_ = try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F10111213141516");
|
||||
|
||||
var ct: [pt.len]u8 = undefined;
|
||||
var tag: [16]u8 = undefined;
|
||||
@ -503,7 +503,7 @@ test "cipher" {
|
||||
{ // test vector (1057) from NIST KAT submission.
|
||||
const ad: [0]u8 = undefined;
|
||||
var pt: [64 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
_ = try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
|
||||
var ct: [pt.len]u8 = undefined;
|
||||
var tag: [16]u8 = undefined;
|
||||
|
||||
@ -1982,23 +1982,34 @@ test "bytes.hex" {
|
||||
pub const trim = @compileError("deprecated; use std.mem.trim with std.ascii.spaces instead");
|
||||
pub const isWhiteSpace = @compileError("deprecated; use std.ascii.isSpace instead");
|
||||
|
||||
pub fn hexToBytes(out: []u8, input: []const u8) !void {
|
||||
if (out.len * 2 < input.len)
|
||||
/// Decodes the sequence of bytes represented by the specified string of
|
||||
/// hexadecimal characters.
|
||||
/// Returns a slice of the output buffer containing the decoded bytes.
|
||||
pub fn hexToBytes(out: []u8, input: []const u8) ![]u8 {
|
||||
// Expect 0 or n pairs of hexadecimal digits.
|
||||
if (input.len & 1 != 0)
|
||||
return error.InvalidLength;
|
||||
if (out.len * 2 < input.len)
|
||||
return error.NoSpaceLeft;
|
||||
|
||||
var in_i: usize = 0;
|
||||
while (in_i != input.len) : (in_i += 2) {
|
||||
while (in_i < input.len) : (in_i += 2) {
|
||||
const hi = try charToDigit(input[in_i], 16);
|
||||
const lo = try charToDigit(input[in_i + 1], 16);
|
||||
out[in_i / 2] = (hi << 4) | lo;
|
||||
}
|
||||
|
||||
return out[0 .. in_i / 2];
|
||||
}
|
||||
|
||||
test "hexToBytes" {
|
||||
const test_hex_str = "909A312BB12ED1F819B3521AC4C1E896F2160507FFC1C8381E3B07BB16BD1706";
|
||||
var pb: [32]u8 = undefined;
|
||||
try hexToBytes(pb[0..], test_hex_str);
|
||||
try expectFmt(test_hex_str, "{X}", .{pb});
|
||||
var buf: [32]u8 = undefined;
|
||||
try expectFmt("90" ** 32, "{X}", .{try hexToBytes(&buf, "90" ** 32)});
|
||||
try expectFmt("ABCD", "{X}", .{try hexToBytes(&buf, "ABCD")});
|
||||
try expectFmt("", "{X}", .{try hexToBytes(&buf, "")});
|
||||
std.testing.expectError(error.InvalidCharacter, hexToBytes(&buf, "012Z"));
|
||||
std.testing.expectError(error.InvalidLength, hexToBytes(&buf, "AAA"));
|
||||
std.testing.expectError(error.NoSpaceLeft, hexToBytes(buf[0..1], "ABAB"));
|
||||
}
|
||||
|
||||
test "formatIntValue with comptime_int" {
|
||||
|
||||
@ -317,7 +317,7 @@ pub const Manifest = struct {
|
||||
cache_hash_file.stat.size = fmt.parseInt(u64, size, 10) catch return error.InvalidFormat;
|
||||
cache_hash_file.stat.inode = fmt.parseInt(fs.File.INode, inode, 10) catch return error.InvalidFormat;
|
||||
cache_hash_file.stat.mtime = fmt.parseInt(i64, mtime_nsec_str, 10) catch return error.InvalidFormat;
|
||||
std.fmt.hexToBytes(&cache_hash_file.bin_digest, digest_str) catch return error.InvalidFormat;
|
||||
_ = std.fmt.hexToBytes(&cache_hash_file.bin_digest, digest_str) catch return error.InvalidFormat;
|
||||
|
||||
if (file_path.len == 0) {
|
||||
return error.InvalidFormat;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user