| author | |
| committer | |
| log | 8f61a7d34a33c2ec912c3f4404d69586e721c75a |
| tree | dee542054a456d4ad6d7d6afbc1c0ef01fcd68e9 |
| parent | b0e7ebc24fdbd17f01180450c0e12f6187ef3f27 |
Previously is was assumed, that all of str[0..max] is readable.5 files changed, 29 insertions(+), 3 deletions(-)
lib/c/string.zig+4-1| ... | @@ -224,7 +224,10 @@ fn stpncpy(noalias dst: [*]c_char, noalias src: [*:0]const c_char, max: usize) c | ... | @@ -224,7 +224,10 @@ fn stpncpy(noalias dst: [*]c_char, noalias src: [*:0]const c_char, max: usize) c |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | fn strnlen(str: [*:0]const c_char, max: usize) callconv(.c) usize { | 226 | fn strnlen(str: [*:0]const c_char, max: usize) callconv(.c) usize { |
| 227 | return std.mem.findScalar(u8, @ptrCast(str[0..max]), 0) orelse max; | 227 | for (0..max) |i| { |
| 228 | if (str[i] == 0) return i; | ||
| 229 | } | ||
| 230 | return max; | ||
| 228 | } | 231 | } |
| 229 | 232 | ||
| 230 | fn memmem(haystack: *const anyopaque, haystack_len: usize, needle: *const anyopaque, needle_len: usize) callconv(.c) ?*anyopaque { | 233 | fn memmem(haystack: *const anyopaque, haystack_len: usize, needle: *const anyopaque, needle_len: usize) callconv(.c) ?*anyopaque { |
lib/c/wchar.zig+5-2| ... | @@ -79,11 +79,14 @@ fn wmemset(dest: [*]wchar_t, elem: wchar_t, len: usize) callconv(.c) [*]wchar_t | ... | @@ -79,11 +79,14 @@ fn wmemset(dest: [*]wchar_t, elem: wchar_t, len: usize) callconv(.c) [*]wchar_t |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | fn wcslen(str: [*:0]const wchar_t) callconv(.c) usize { | 81 | fn wcslen(str: [*:0]const wchar_t) callconv(.c) usize { |
| 82 | return wcsnlen(str, std.math.maxInt(usize)); | 82 | return std.mem.len(str); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | fn wcsnlen(str: [*:0]const wchar_t, max: usize) callconv(.c) usize { | 85 | fn wcsnlen(str: [*:0]const wchar_t, max: usize) callconv(.c) usize { |
| 86 | return std.mem.findScalar(wchar_t, str[0..max], 0) orelse max; | 86 | for (0..max) |i| { |
| 87 | if (str[i] == 0) return i; | ||
| 88 | } | ||
| 89 | return max; | ||
| 87 | } | 90 | } |
| 88 | 91 | ||
| 89 | fn wcscmp(a: [*:0]const wchar_t, b: [*:0]const wchar_t) callconv(.c) c_int { | 92 | fn wcscmp(a: [*:0]const wchar_t, b: [*:0]const wchar_t) callconv(.c) c_int { |
lib/std/c.zig+2| ... | @@ -11471,7 +11471,9 @@ pub const strdup = switch (builtin.abi) { | ... | @@ -11471,7 +11471,9 @@ pub const strdup = switch (builtin.abi) { |
| 11471 | .msvc => private._strdup, | 11471 | .msvc => private._strdup, |
| 11472 | else => private.strdup, | 11472 | else => private.strdup, |
| 11473 | }; | 11473 | }; |
| 11474 | pub extern "c" fn strnlen(s: [*:0]const c_char, n: usize) callconv(.c) usize; | ||
| 11474 | pub extern "c" fn strndup(s: [*:0]const c_char, n: usize) ?[*:0]c_char; | 11475 | pub extern "c" fn strndup(s: [*:0]const c_char, n: usize) ?[*:0]c_char; |
| 11476 | pub extern "c" fn wcsnlen(s: [*:0]const wchar_t, n: usize) callconv(.c) usize; | ||
| 11475 | pub const wcsdup = switch (builtin.abi) { | 11477 | pub const wcsdup = switch (builtin.abi) { |
| 11476 | .msvc => private._wcsdup, | 11478 | .msvc => private._wcsdup, |
| 11477 | else => private.wcsdup, | 11479 | else => private.wcsdup, |
test/c/string.zig+9| ... | @@ -50,3 +50,12 @@ test "strndup" { | ... | @@ -50,3 +50,12 @@ test "strndup" { |
| 50 | const copy3_u8: [*:0]u8 = @ptrCast(copy3); | 50 | const copy3_u8: [*:0]u8 = @ptrCast(copy3); |
| 51 | try testing.expectEqualStrings("Hello", std.mem.span(@as([*:0]const u8, copy3_u8))); | 51 | try testing.expectEqualStrings("Hello", std.mem.span(@as([*:0]const u8, copy3_u8))); |
| 52 | } | 52 | } |
| 53 | |||
| 54 | test "strnlen" { | ||
| 55 | const str: [*:0]const u8 = "Hello"; | ||
| 56 | try testing.expectEqual(3, c.strnlen(@ptrCast(str), 3)); | ||
| 57 | try testing.expectEqual(4, c.strnlen(@ptrCast(str), 4)); | ||
| 58 | try testing.expectEqual(5, c.strnlen(@ptrCast(str), 5)); | ||
| 59 | try testing.expectEqual(5, c.strnlen(@ptrCast(str), 6)); | ||
| 60 | try testing.expectEqual(5, c.strnlen(@ptrCast(str), 7)); | ||
| 61 | } |
test/c/wchar.zig+9| ... | @@ -32,3 +32,12 @@ test "wcsdup empty string" { | ... | @@ -32,3 +32,12 @@ test "wcsdup empty string" { |
| 32 | defer c.free(cpy); | 32 | defer c.free(cpy); |
| 33 | try testing.expectEqual(@as(c.wchar_t, 0), cpy[0]); | 33 | try testing.expectEqual(@as(c.wchar_t, 0), cpy[0]); |
| 34 | } | 34 | } |
| 35 | |||
| 36 | test "wcsnlen" { | ||
| 37 | const wcs: [*:0]const c.wchar_t = &.{ 'H', 'e', 'l', 'l', 'o' }; | ||
| 38 | try testing.expectEqual(3, c.wcsnlen(wcs, 3)); | ||
| 39 | try testing.expectEqual(4, c.wcsnlen(wcs, 4)); | ||
| 40 | try testing.expectEqual(5, c.wcsnlen(wcs, 5)); | ||
| 41 | try testing.expectEqual(5, c.wcsnlen(wcs, 6)); | ||
| 42 | try testing.expectEqual(5, c.wcsnlen(wcs, 7)); | ||
| 43 | } |