diff options
author | David Benjamin <davidben@chromium.org> | 2015-12-17 09:06:10 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2015-12-22 03:23:52 +0300 |
commit | 4cc671cbf4d3834b1570005bc7b478a845dc9583 (patch) | |
tree | ec07efd4e2f300642776e42bfacf12d8ae1a04cd /crypto | |
parent | e13263d5e4d4bf479d2ef198b1ff3f4946312236 (diff) |
Add CBB_reserve and CBB_did_write.
These will be needed when we start writing variable-length things to a
CBB.
Change-Id: Ie7b9b140f5f875b43adedc8203ce9d3f4068dfea
Reviewed-on: https://boringssl-review.googlesource.com/6764
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/bytestring/bytestring_test.cc | 27 | ||||
-rw-r--r-- | crypto/bytestring/cbb.c | 35 |
2 files changed, 56 insertions, 6 deletions
diff --git a/crypto/bytestring/bytestring_test.cc b/crypto/bytestring/bytestring_test.cc index 8a178126..188c63d5 100644 --- a/crypto/bytestring/bytestring_test.cc +++ b/crypto/bytestring/bytestring_test.cc @@ -703,12 +703,32 @@ static bool TestASN1Uint64() { return true; } -static int TestZero() { +static bool TestZero() { CBB cbb; CBB_zero(&cbb); // Calling |CBB_cleanup| on a zero-state |CBB| must not crash. CBB_cleanup(&cbb); - return 1; + return true; +} + +static bool TestCBBReserve() { + uint8_t buf[10]; + uint8_t *ptr; + size_t len; + ScopedCBB cbb; + if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) || + // Too large. + CBB_reserve(cbb.get(), &ptr, 11) || + // Successfully reserve the entire space. + !CBB_reserve(cbb.get(), &ptr, 10) || + ptr != buf || + // Advancing under the maximum bytes is legal. + !CBB_did_write(cbb.get(), 5) || + !CBB_finish(cbb.get(), NULL, &len) || + len != 5) { + return false; + } + return true; } int main(void) { @@ -729,7 +749,8 @@ int main(void) { !TestBerConvert() || !TestASN1Uint64() || !TestGetOptionalASN1Bool() || - !TestZero()) { + !TestZero() || + !TestCBBReserve()) { return 1; } diff --git a/crypto/bytestring/cbb.c b/crypto/bytestring/cbb.c index a1bc0121..a9e9b3cb 100644 --- a/crypto/bytestring/cbb.c +++ b/crypto/bytestring/cbb.c @@ -84,8 +84,8 @@ void CBB_cleanup(CBB *cbb) { cbb->base = NULL; } -static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, - size_t len) { +static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { size_t newlen; if (base == NULL) { @@ -121,7 +121,17 @@ static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, if (out) { *out = base->buf + base->len; } - base->len = newlen; + + return 1; +} + +static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { + if (!cbb_buffer_reserve(base, out, len)) { + return 0; + } + /* This will not overflow or |cbb_buffer_reserve| would have failed. */ + base->len += len; return 1; } @@ -339,6 +349,25 @@ int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { return 1; } +int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) { + if (!CBB_flush(cbb) || + !cbb_buffer_reserve(cbb->base, out_data, len)) { + return 0; + } + return 1; +} + +int CBB_did_write(CBB *cbb, size_t len) { + size_t newlen = cbb->base->len + len; + if (cbb->child != NULL || + newlen < cbb->base->len || + newlen > cbb->base->cap) { + return 0; + } + cbb->base->len = newlen; + return 1; +} + int CBB_add_u8(CBB *cbb, uint8_t value) { if (!CBB_flush(cbb)) { return 0; |