hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 842b4d0edcea4006eef3ec0177c08dbb9e319fc2
parent 088579531180231b851b7e0db2392d542a8a10f1
Author: Bor Grošelj Simić <bgs@turminal.net>
Date:   Fri, 27 May 2022 23:09:35 +0200

encoding::pem: fix an issue with short writes

Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>

Diffstat:
Mencoding/pem/+test.ha | 10++++++++++
Mencoding/pem/pem.ha | 17++++++++++++++++-
2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/encoding/pem/+test.ha b/encoding/pem/+test.ha @@ -61,6 +61,16 @@ use strio; io::close(&stream)!; assert(strio::string(&out) == privkey_str); io::close(&out)!; + + // test short writes + let out = strio::dynamic(); + const stream = newencoder("CERTIFICATE", &out)!; + for (let i = 0z; i < len(testcert_bin); i += 1) { + io::write(&stream, [testcert_bin[i]])!; + }; + io::close(&stream)!; + assert(strio::string(&out) == cert_str); + io::close(&out)!; }; const cert_str: str = diff --git a/encoding/pem/pem.ha b/encoding/pem/pem.ha @@ -202,6 +202,8 @@ export type pemencoder = struct { out: io::handle, b64: base64::encoder, label: str, + buf: [48]u8, + ln: u8, }; const pemencoder_vt: io::vtable = io::vtable { @@ -219,22 +221,35 @@ export fn newencoder(label: str, s: io::handle) (pemencoder | io::error) = { out = s, b64 = base64::newencoder(&base64::std_encoding, s), label = label, + ... }; }; fn pem_write(s: *io::stream, buf: const []u8) (size | io::error) = { let s = s: *pemencoder; let buf = buf: []u8; + if (len(buf) < len(s.buf) - s.ln) { + s.buf[s.ln..s.ln+len(buf)] = buf[..]; + s.ln += len(buf): u8; + return len(buf); + }; let z = 0z; + s.buf[s.ln..] = buf[..len(s.buf) - s.ln]; + z += io::writeall(&s.b64, s.buf)?; + z += io::write(s.out, ['\n'])?; + buf = buf[len(s.buf) - s.ln..]; for (len(buf) >= 48; buf = buf[48..]) { z += io::writeall(&s.b64, buf[..48])?; z += io::write(s.out, ['\n'])?; }; - return z + io::writeall(&s.b64, buf)?; + s.ln = len(buf): u8; + s.buf[..s.ln] = buf; + return z + s.ln; }; fn pem_wclose(s: *io::stream) (void | io::error) = { let s = s: *pemencoder; + io::writeall(&s.b64, s.buf[..s.ln])?; io::close(&s.b64)?; fmt::fprintf(s.out, "\n{}{}{}\n", end, s.label, suffix)?; };