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>
This commit is contained in:
David Benjamin 2015-12-17 01:06:10 -05:00 committed by Adam Langley
parent e13263d5e4
commit 4cc671cbf4
3 changed files with 67 additions and 6 deletions

View File

@ -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;
}

View File

@ -84,7 +84,7 @@ void CBB_cleanup(CBB *cbb) {
cbb->base = NULL;
}
static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out,
size_t len) {
size_t newlen;
@ -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;

View File

@ -331,6 +331,17 @@ OPENSSL_EXPORT int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
* otherwise. */
OPENSSL_EXPORT int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
/* CBB_reserve ensures |cbb| has room for |len| additional bytes and sets
* |*out_data| to point to the beginning of that space. It returns one on
* success and zero otherwise. The caller may write up to |len| bytes to
* |*out_data| and call |CBB_did_write| to complete the write. |*out_data| is
* valid until the next operation on |cbb| or an ancestor |CBB|. */
OPENSSL_EXPORT int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len);
/* CBB_did_write advances |cbb| by |len| bytes, assuming the space has been
* written to by the caller. It returns one on success and zero on error. */
OPENSSL_EXPORT int CBB_did_write(CBB *cbb, size_t len);
/* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
* success and zero otherwise. */
OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value);