1/* $OpenBSD: test_sshbuf.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ 2/* 3 * Regress test for sshbuf.h buffer API 4 * 5 * Placed in the public domain 6 */ 7 8#include <sys/types.h> 9#include <stdio.h> 10#include <stdint.h> 11#include <stdlib.h> 12#include <string.h> 13 14#include "test_helper.h" 15 16#include "ssherr.h" 17#define SSHBUF_INTERNAL 1 /* access internals for testing */ 18#include "sshbuf.h" 19 20void sshbuf_tests(void); 21 22#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 23 24void 25sshbuf_tests(void) 26{ 27 struct sshbuf *p1; 28 const u_char *cdp; 29 u_char *dp; 30 size_t sz; 31 int r; 32 33 TEST_START("allocate sshbuf"); 34 p1 = sshbuf_new(); 35 ASSERT_PTR_NE(p1, NULL); 36 TEST_DONE(); 37 38 TEST_START("max size on fresh buffer"); 39 ASSERT_SIZE_T_GT(sshbuf_max_size(p1), 0); 40 TEST_DONE(); 41 42 TEST_START("available on fresh buffer"); 43 ASSERT_SIZE_T_GT(sshbuf_avail(p1), 0); 44 TEST_DONE(); 45 46 TEST_START("len = 0 on empty buffer"); 47 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 48 TEST_DONE(); 49 50 TEST_START("set valid max size"); 51 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 65536), 0); 52 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 65536); 53 TEST_DONE(); 54 55 TEST_START("available on limited buffer"); 56 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 65536); 57 TEST_DONE(); 58 59 TEST_START("free"); 60 sshbuf_free(p1); 61 TEST_DONE(); 62 63 TEST_START("consume on empty buffer"); 64 p1 = sshbuf_new(); 65 ASSERT_PTR_NE(p1, NULL); 66 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); 67 ASSERT_INT_EQ(sshbuf_consume(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); 68 sshbuf_free(p1); 69 TEST_DONE(); 70 71 TEST_START("consume_end on empty buffer"); 72 p1 = sshbuf_new(); 73 ASSERT_PTR_NE(p1, NULL); 74 ASSERT_INT_EQ(sshbuf_consume_end(p1, 0), 0); 75 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), SSH_ERR_MESSAGE_INCOMPLETE); 76 sshbuf_free(p1); 77 TEST_DONE(); 78 79 TEST_START("reserve space"); 80 p1 = sshbuf_new(); 81 ASSERT_PTR_NE(p1, NULL); 82 r = sshbuf_reserve(p1, 1, &dp); 83 ASSERT_INT_EQ(r, 0); 84 ASSERT_PTR_NE(dp, NULL); 85 *dp = 0x11; 86 r = sshbuf_reserve(p1, 3, &dp); 87 ASSERT_INT_EQ(r, 0); 88 ASSERT_PTR_NE(dp, NULL); 89 *dp++ = 0x22; 90 *dp++ = 0x33; 91 *dp++ = 0x44; 92 TEST_DONE(); 93 94 TEST_START("sshbuf_len on filled buffer"); 95 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 96 TEST_DONE(); 97 98 TEST_START("sshbuf_ptr on filled buffer"); 99 cdp = sshbuf_ptr(p1); 100 ASSERT_PTR_NE(cdp, NULL); 101 ASSERT_U8_EQ(cdp[0], 0x11); 102 ASSERT_U8_EQ(cdp[1], 0x22); 103 ASSERT_U8_EQ(cdp[2], 0x33); 104 ASSERT_U8_EQ(cdp[3], 0x44); 105 TEST_DONE(); 106 107 TEST_START("consume on filled buffer"); 108 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 109 ASSERT_INT_EQ(sshbuf_consume(p1, 0), 0); 110 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 111 r = sshbuf_consume(p1, 64); 112 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 113 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 114 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); 115 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 3); 116 cdp = sshbuf_ptr(p1); 117 ASSERT_PTR_NE(p1, NULL); 118 ASSERT_U8_EQ(cdp[0], 0x22); 119 ASSERT_INT_EQ(sshbuf_consume(p1, 2), 0); 120 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); 121 cdp = sshbuf_ptr(p1); 122 ASSERT_PTR_NE(p1, NULL); 123 ASSERT_U8_EQ(cdp[0], 0x44); 124 r = sshbuf_consume(p1, 2); 125 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 126 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); 127 ASSERT_INT_EQ(sshbuf_consume(p1, 1), 0); 128 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 129 r = sshbuf_consume(p1, 1); 130 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 131 sshbuf_free(p1); 132 TEST_DONE(); 133 134 TEST_START("consume_end on filled buffer"); 135 p1 = sshbuf_new(); 136 ASSERT_PTR_NE(p1, NULL); 137 r = sshbuf_reserve(p1, 4, &dp); 138 ASSERT_INT_EQ(r, 0); 139 ASSERT_PTR_NE(dp, NULL); 140 *dp++ = 0x11; 141 *dp++ = 0x22; 142 *dp++ = 0x33; 143 *dp++ = 0x44; 144 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 145 r = sshbuf_consume_end(p1, 5); 146 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 147 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4); 148 ASSERT_INT_EQ(sshbuf_consume_end(p1, 3), 0); 149 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); 150 cdp = sshbuf_ptr(p1); 151 ASSERT_PTR_NE(cdp, NULL); 152 ASSERT_U8_EQ(*cdp, 0x11); 153 r = sshbuf_consume_end(p1, 2); 154 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 155 ASSERT_INT_EQ(sshbuf_consume_end(p1, 1), 0); 156 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 157 sshbuf_free(p1); 158 TEST_DONE(); 159 160 TEST_START("fill limited buffer"); 161 p1 = sshbuf_new(); 162 ASSERT_PTR_NE(p1, NULL); 163 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); 164 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); 165 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); 166 r = sshbuf_reserve(p1, 1223, &dp); 167 ASSERT_INT_EQ(r, 0); 168 ASSERT_PTR_NE(dp, NULL); 169 memset(dp, 0xd7, 1223); 170 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); 171 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 0); 172 r = sshbuf_reserve(p1, 1, &dp); 173 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 174 ASSERT_PTR_EQ(dp, NULL); 175 TEST_DONE(); 176 177 TEST_START("consume and force compaction"); 178 ASSERT_INT_EQ(sshbuf_consume(p1, 223), 0); 179 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); 180 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); 181 r = sshbuf_reserve(p1, 224, &dp); 182 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 183 ASSERT_PTR_EQ(dp, NULL); 184 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1000); 185 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 223); 186 r = sshbuf_reserve(p1, 223, &dp); 187 ASSERT_INT_EQ(r, 0); 188 ASSERT_PTR_NE(dp, NULL); 189 memset(dp, 0x7d, 223); 190 cdp = sshbuf_ptr(p1); 191 ASSERT_PTR_NE(cdp, NULL); 192 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); 193 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); 194 TEST_DONE(); 195 196 TEST_START("resize full buffer"); 197 r = sshbuf_set_max_size(p1, 1000); 198 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 199 sz = roundup(1223 + SSHBUF_SIZE_INC * 3, SSHBUF_SIZE_INC); 200 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sz), 0); 201 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz); 202 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - 1223); 203 ASSERT_INT_EQ(sshbuf_len(p1), 1223); 204 TEST_DONE(); 205 206 /* NB. uses sshbuf internals */ 207 TEST_START("alloc chunking"); 208 r = sshbuf_reserve(p1, 1, &dp); 209 ASSERT_INT_EQ(r, 0); 210 ASSERT_PTR_NE(dp, NULL); 211 *dp = 0xff; 212 cdp = sshbuf_ptr(p1); 213 ASSERT_PTR_NE(cdp, NULL); 214 ASSERT_MEM_FILLED_EQ(cdp, 0xd7, 1000); 215 ASSERT_MEM_FILLED_EQ(cdp + 1000, 0x7d, 223); 216 ASSERT_MEM_FILLED_EQ(cdp + 1223, 0xff, 1); 217 ASSERT_SIZE_T_EQ(sshbuf_alloc(p1) % SSHBUF_SIZE_INC, 0); 218 sshbuf_free(p1); 219 TEST_DONE(); 220 221 TEST_START("reset buffer"); 222 p1 = sshbuf_new(); 223 ASSERT_PTR_NE(p1, NULL); 224 ASSERT_INT_EQ(sshbuf_set_max_size(p1, 1223), 0); 225 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); 226 r = sshbuf_reserve(p1, 1223, &dp); 227 ASSERT_INT_EQ(r, 0); 228 ASSERT_PTR_NE(dp, NULL); 229 memset(dp, 0xd7, 1223); 230 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1223); 231 sshbuf_reset(p1); 232 ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), 1223); 233 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 234 ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); 235 sshbuf_free(p1); 236 TEST_DONE(); 237} 238