commit 37e7f3e666a32c82836915be63dce0699481ab3a
parent 62c7f5218df795c0b7936eab3a567322e4b84f5e
Author: Sebastian <sebastian@sebsite.pw>
Date: Fri, 13 Jan 2023 14:20:29 -0500
all: don't autofill fields without a default value
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
16 files changed, 86 insertions(+), 67 deletions(-)
diff --git a/bufio/buffered.ha b/bufio/buffered.ha
@@ -59,23 +59,28 @@ export fn buffered(
wbuf: []u8,
) bufstream = {
static let flush_default = ['\n': u8];
- let s = bufstream {
+
+ let stream =
+ if (len(rbuf) != 0 && len(wbuf) != 0) {
+ assert(rbuf: *[*]u8 != wbuf: *[*]u8,
+ "Cannot use bufio::buffered with same buffer for reads and writes");
+ yield &buffered_vtable_rw;
+ } else if (len(rbuf) != 0) {
+ yield &buffered_vtable_r;
+ } else if (len(wbuf) != 0) {
+ yield &buffered_vtable_w;
+ } else {
+ abort("Must provide at least one buffer to bufio::buffered");
+ };
+
+ return bufstream {
+ stream = stream,
source = src,
rbuffer = rbuf,
wbuffer = wbuf,
flush = flush_default,
...
};
- if (len(rbuf) != 0 && len(wbuf) != 0) {
- assert(rbuf: *[*]u8 != wbuf: *[*]u8,
- "Cannot use bufio::buffered with same buffer for reads and writes");
- s.stream = &buffered_vtable_rw;
- } else if (len(rbuf) != 0) {
- s.stream = &buffered_vtable_r;
- } else if (len(wbuf) != 0) {
- s.stream = &buffered_vtable_w;
- } else abort("Must provide at least one buffer to bufio::buffered");
- return s;
};
// Flushes pending writes to the underlying stream.
diff --git a/crypto/chacha/chacha20.ha b/crypto/chacha/chacha20.ha
@@ -36,6 +36,8 @@ export type stream = struct {
// with [[io::close]] after use to wipe sensitive data from memory.
export fn chacha20() stream = {
return stream {
+ stream = &cipher::xorstream_vtable,
+ h = 0,
keybuf = &keybuf,
advance = &advance,
finish = &finish,
@@ -52,7 +54,7 @@ export fn chacha20_init(
key: *[KEYSIZE]u8,
nonce: *[NONCESIZE]u8
) void = {
- cipher::xorstream_init(s, h);
+ s.h = h;
s.state[0] = magic[0];
s.state[1] = magic[1];
@@ -69,8 +71,6 @@ export fn chacha20_init(
s.state[13] = endian::legetu32(nonce[0..4]);
s.state[14] = endian::legetu32(nonce[4..8]);
s.state[15] = endian::legetu32(nonce[8..12]);
-
- s.xorused = BLOCKSIZE;
};
// Initialise a XChacha20 stream.
diff --git a/crypto/cipher/ctr.ha b/crypto/cipher/ctr.ha
@@ -54,6 +54,8 @@ export fn ctr(h: io::handle, b: *block, iv: []u8, buf: []u8) ctr_stream = {
};
let s = ctr_stream {
+ stream = &xorstream_vtable,
+ h = h,
keybuf = &ctr_keybuf,
advance = &ctr_advance,
finish = &ctr_finish,
@@ -65,7 +67,6 @@ export fn ctr(h: io::handle, b: *block, iv: []u8, buf: []u8) ctr_stream = {
xorused = xorbufsz,
...
};
- xorstream_init(&s, h);
return s;
};
diff --git a/crypto/cipher/gcm.ha b/crypto/cipher/gcm.ha
@@ -13,7 +13,7 @@ export def GCMTAGSIZE: size = 16;
export type gcmstream = struct {
stream: io::stream,
- block: *block,
+ block: nullable *block,
handle: io::handle,
tagbuf: [GCMBLOCKSIZE]u8,
xorbuf: [GCMBLOCKSIZE]u8,
@@ -51,6 +51,7 @@ const gcm_vtable: io::vtable = io::vtable {
export fn gcm() gcmstream = {
return gcmstream {
stream = &gcm_vtable,
+ handle = 0,
...
};
};
@@ -144,7 +145,7 @@ fn fillxorbuf(s: *gcmstream) void = {
let y: [GCMBLOCKSIZE]u8 = [0...];
s.xorbuf[..] = s.y0[..];
beputu32(s.xorbuf[12..], s.y);
- encrypt(s.block, s.xorbuf, s.xorbuf);
+ encrypt(s.block as *block, s.xorbuf, s.xorbuf);
s.y += 1;
s.xorbufpos = 0;
};
@@ -205,7 +206,7 @@ export fn gcm_seal(s: *gcmstream, tag: []u8) void = {
ghash_ctmul64(s.tagbuf, s.h, tag);
// use tmp to store the resulting tag
- encrypt(s.block, tag, s.y0);
+ encrypt(s.block as *block, tag, s.y0);
xor(tag, tag, s.tagbuf);
};
@@ -225,7 +226,7 @@ export fn gcm_verify(s: *gcmstream, tag: []u8) (void | errors::invalid) = {
ghash_ctmul64(s.tagbuf, s.h, tmp);
- encrypt(s.block, tmp, s.y0);
+ encrypt(s.block as *block, tmp, s.y0);
xor(tmp, tmp, s.tagbuf);
if (eqslice(tag, tmp) == 0) {
@@ -241,5 +242,7 @@ fn gcm_closer(s: *io::stream) (void | io::error) = {
bytes::zero(s.y0);
bytes::zero(s.h);
- finish(s.block);
+ if (s.block is *block) {
+ finish(s.block as *block);
+ };
};
diff --git a/crypto/cipher/stream.ha b/crypto/cipher/stream.ha
@@ -4,9 +4,8 @@ use io;
use crypto::math::{xor};
// An abstract interface for implementing streams that encrypt or decrypt by
-// producing a key stream that is xored with the data. The implementing stream
-// must call [[xorstream_init]] after creation so that [[io::reader]],
-// [[io::writer]] and [[io::closer]] functions will be registered.
+// producing a key stream that is xored with the data. The stream field should
+// be set to &[[xorstream_vtable]].
//
// After initializing the xorstream can be written to with [[io::write]] to
// encrypt data and write it to the handle 'h'. For decrpytion 'h' will provide
@@ -27,14 +26,7 @@ export type xorstream = struct {
finish: *fn(s: *xorstream) void,
};
-// Initialises a xorstream with the handle 'h' and sets [[io::reader]],
-// [[io::writer]] and [[io::closer]] functions.
-export fn xorstream_init(xs: *xorstream, h: io::handle) void = {
- xs.h = h;
- xs.stream = &xorstream_vtable;
-};
-
-const xorstream_vtable: io::vtable = io::vtable {
+export const xorstream_vtable: io::vtable = io::vtable {
writer = &xor_writer,
reader = &xor_reader,
closer = &xor_closer,
diff --git a/crypto/salsa/salsa20.ha b/crypto/salsa/salsa20.ha
@@ -35,6 +35,8 @@ export type stream = struct {
// after use to wipe sensitive data from memory.
export fn salsa20() stream = {
return stream {
+ stream = &cipher::xorstream_vtable,
+ h = 0,
keybuf = &keybuf,
advance = &advance,
finish = &finish,
@@ -80,9 +82,7 @@ export fn salsa20_init(
let counter: [8]u8 = [0...];
init(&s.state, key, nonce, &counter);
- s.xorused = BLOCKSIZE;
-
- cipher::xorstream_init(s, h);
+ s.h = h;
};
// Initialize an XSalsa20 stream. XSalsa20 differs from Salsa20 via the use of a
diff --git a/encoding/pem/pem.ha b/encoding/pem/pem.ha
@@ -112,8 +112,13 @@ export fn next(dec: *decoder) ((str, pemdecoder) | io::EOF | io::error) = {
return (strio::string(&dec.label), pemdecoder {
stream = &pemdecoder_vt,
in = &dec.in,
+ b64_in = b64stream {
+ stream = &b64stream_r_vt,
+ in = &dec.in,
+ },
+ // forcefully zero field (it's actually set in pem_read)
+ b64 = *(&([0...]: [size(base64::decoder)]u8): *base64::decoder),
b64_ready = false,
- ...
});
};
@@ -128,10 +133,6 @@ fn pem_read(st: *io::stream, buf: []u8) (size | io::EOF | io::error) = {
const st = st: *pemdecoder;
assert(st.stream.reader == &pem_read);
if (!st.b64_ready) {
- st.b64_in = b64stream {
- stream = &b64stream_r_vt,
- in = st.in,
- };
st.b64 = base64::newdecoder(&base64::std_encoding, &st.b64_in);
st.b64_ready = true;
};
diff --git a/format/tar/reader.ha b/format/tar/reader.ha
@@ -58,23 +58,33 @@ export fn next(rd: *reader) (entry | error | io::EOF) = {
return io::EOF;
};
- let ent = entry { ... };
const reader = bufio::fixed(buf, io::mode::READ);
const name = readstr(&reader, 100);
- ent.mode = readoct(&reader, 8)?;
- ent.uid = readoct(&reader, 8)?;
- ent.gid = readoct(&reader, 8)?;
- ent.fsize = readsize(&reader, 12)?;
- ent.mtime = readoct(&reader, 12)?;
- ent.checksum = readoct(&reader, 8)?;
- ent.etype = readoct(&reader, 1)?: entry_type;
- ent.link = readstr(&reader, 100);
-
- if (ent.etype == entry_type::FILE) {
- ent.vtable = &file_vtable;
- ent.src = rd.src;
- ent.orig = ent.fsize;
- ent.remain = ent.orig;
+ const mode = readoct(&reader, 8)?;
+ const uid = readoct(&reader, 8)?;
+ const gid = readoct(&reader, 8)?;
+ const fsize = readsize(&reader, 12)?;
+ const mtime = readoct(&reader, 12)?;
+ const checksum = readoct(&reader, 8)?;
+ const etype = readoct(&reader, 1)?: entry_type;
+ const link = readstr(&reader, 100);
+
+ let ent = entry {
+ vtable = if (etype == entry_type::FILE) &file_vtable
+ else &nonfile_vtable,
+ src = rd.src,
+ orig = fsize,
+ remain = fsize,
+ name = name,
+ mode = mode,
+ uid = uid,
+ gid = gid,
+ fsize = fsize,
+ mtime = mtime,
+ checksum = checksum,
+ etype = etype,
+ link = link,
+ ...
};
const ustar = readstr(&reader, 6);
@@ -117,6 +127,8 @@ const file_vtable: io::vtable = io::vtable {
...
};
+const nonfile_vtable: io::vtable = io::vtable { ... };
+
fn file_read(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = {
let ent = s: *ent_reader;
assert(ent.vtable == &file_vtable);
diff --git a/hare/unit/context.ha b/hare/unit/context.ha
@@ -5,5 +5,5 @@ use hare::types;
type context = struct {
store: *types::typestore,
scope: *scope,
- fntype: *types::func,
+ fntype: nullable *types::func,
};
diff --git a/hare/unit/process.ha b/hare/unit/process.ha
@@ -405,7 +405,7 @@ fn process_return(ctx: *context, aexpr: *ast::expr) (*expr | error) = {
case let aexpr: *ast::expr =>
yield process_expr(ctx, aexpr)?;
};
- // TODO: assert(types::assignable(ctx.fntype.result, rval.type));
+ // TODO: assert(types::assignable(ctx.fntype.result as *types::func, rval.type));
return alloc(expr {
start = aexpr.start,
end = aexpr.end,
diff --git a/net/+freebsd.ha b/net/+freebsd.ha
@@ -21,15 +21,13 @@ export type sockflags = enum int {
// available. Optionally accepts NOCLOEXEC and NONBLOCK flags. If flags are
// supplied, the [[io::file]] returned will have the supplied flags set.
export fn accept(sock: socket, flags: sockflags...) (socket | error) = {
- let sn = rt::sockaddr {...};
- const sz = size(rt::sockaddr): u32;
// Apply any supplied flags
let f = 0i;
for (let i = 0z; i < len(flags); i += 1) {
f |= flags[i];
};
f ^= rt::SOCK_CLOEXEC; // invert CLOEXEC
- const fd = match (rt::accept4(sock, &sn, &sz, f)) {
+ const fd = match (rt::accept4(sock, null, null, f)) {
case let err: rt::errno =>
return errors::errno(err);
case let fd: int =>
diff --git a/net/+linux.ha b/net/+linux.ha
@@ -21,15 +21,13 @@ export type sockflags = enum int {
// available. Optionally accepts NOCLOEXEC and NONBLOCK flags. If flags are
// supplied, the [[io::file]] returned will have the supplied flags set.
export fn accept(sock: socket, flags: sockflags...) (socket | error) = {
- let sn = rt::sockaddr {...};
- const sz = size(rt::sockaddr): u32;
// Apply any supplied flags
let f = 0i;
for (let i = 0z; i < len(flags); i += 1) {
f |= flags[i];
};
f ^= rt::SOCK_CLOEXEC; // invert CLOEXEC
- const fd = match (rt::accept4(sock, &sn, &sz, f: int)) {
+ const fd = match (rt::accept4(sock, null, null, f: int)) {
case let err: rt::errno =>
return errors::errno(err);
case let fd: int =>
diff --git a/os/+linux/stdfd.ha b/os/+linux/stdfd.ha
@@ -6,11 +6,15 @@ use io;
use rt;
let stdin_bufio: bufio::bufstream = bufio::bufstream {
+ // Will be overwritten, but must be initialized
+ stream = null: io::stream,
source = 0,
...
};
let stdout_bufio: bufio::bufstream = bufio::bufstream {
+ // Will be overwritten, but must be initialized
+ stream = null: io::stream,
source = 1,
...
};
diff --git a/unix/poll/+freebsd.ha b/unix/poll/+freebsd.ha
@@ -18,8 +18,8 @@ export type event = enum i16 {
// A single file descriptor to be polled.
export type pollfd = struct {
fd: io::file,
- events: event,
- revents: event,
+ events: i16,
+ revents: i16,
};
// Pass this [[time::duration]] to [[poll]] to cause it wait indefinitely for
diff --git a/unix/poll/+linux.ha b/unix/poll/+linux.ha
@@ -18,8 +18,8 @@ export type event = enum i16 {
// A single file descriptor to be polled.
export type pollfd = struct {
fd: io::file,
- events: event,
- revents: event,
+ events: i16,
+ revents: i16,
};
// Pass this [[time::duration]] to [[poll]] to cause it wait indefinitely for
diff --git a/unix/signal/+linux.ha b/unix/signal/+linux.ha
@@ -36,7 +36,12 @@ export fn handle(
// Filled in by rt:
sa_restorer = null: *fn () void,
};
- let old = rt::sigact { ... };
+ let old = rt::sigact {
+ // Filled in by rt:
+ sa_sigaction = null: *fn(_: int, _: *rt::siginfo, _: *void) void,
+ sa_restorer = null: *fn() void,
+ ...
+ };
match (rt::sigaction(signum, &new, &old)) {
case int =>
yield;