• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

proftpd / proftpd / 28531645955

01 Jul 2026 04:14PM UTC coverage: 92.468% (-0.6%) from 93.032%
28531645955

push

github

web-flow
Exercise caution when reading the client-provided file size for SCP uploads, as it could possibly overflow our size type.

Thanks to Fabian Wahle of Hap Security for reporting this issue.

48701 of 52668 relevant lines covered (92.47%)

227.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.58
/tests/api/table.c
1
/*
2
 * ProFTPD - FTP server testsuite
3
 * Copyright (c) 2008-2026 The ProFTPD Project team
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
17
 *
18
 * As a special exemption, The ProFTPD Project team and other respective
19
 * copyright holders give permission to link this program with OpenSSL, and
20
 * distribute the resulting executable, without including the source code for
21
 * OpenSSL in the source distribution.
22
 */
23

24
/* Table API tests */
25

26
#include "tests.h"
27

28
static pool *p = NULL;
29

30
/* Fixtures */
31

32
static void set_up(void) {
20✔
33
  if (p == NULL) {
20✔
34
    p = make_sub_pool(NULL);
20✔
35
  }
36
}
20✔
37

38
static void tear_down(void) {
20✔
39
  if (p) {
20✔
40
    destroy_pool(p);
20✔
41
    p = NULL;
20✔
42
  }
43
}
20✔
44

45
/* Helper functions */
46

47
static unsigned int b_val_count = 0;
48

49
static int do_cb(const void *key, size_t keysz, const void *value,
3✔
50
    size_t valuesz, void *user_data) {
51

52
  if (*((const char *) value) == 'b') {
3✔
53
    b_val_count++;
3✔
54
  }
55

56
  return -1;
3✔
57
}
58

59
static int do_with_remove_cb(const void *key, size_t keysz, const void *value,
2✔
60
    size_t valuesz, void *user_data) {
61
  pr_table_t *tab;
62

63
  tab = user_data;
2✔
64

65
  if (*((const char *) value) == 'b') {
2✔
66
    b_val_count++;
2✔
67
  }
68

69
  pr_table_kremove(tab, key, keysz, NULL);
2✔
70
  return 0;
2✔
71
}
72

73
static void table_dump(const char *fmt, ...) {
×
74
}
×
75

76
/* Tests */
77

78
START_TEST (table_alloc_test) {
1✔
79
  pr_table_t *tab;
80

81
  tab = pr_table_alloc(NULL, 0);
1✔
82
  ck_assert_msg(tab == NULL, "Failed to handle null arguments");
1✔
83
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
84

85
  tab = pr_table_alloc(p, 0);
1✔
86
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
2✔
87
}
88
END_TEST
1✔
89

90
START_TEST (table_nalloc_test) {
1✔
91
  pr_table_t *tab;
92

93
  tab = pr_table_nalloc(NULL, 0, 0);
1✔
94
  ck_assert_msg(tab == NULL, "Failed to handle null arguments");
1✔
95
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
96

97
  tab = pr_table_nalloc(p, 0, 0);
1✔
98
  ck_assert_msg(tab == NULL, "Failed to handle zero chains");
2✔
99
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
100

101
  tab = pr_table_nalloc(p, 0, 1);
1✔
102
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
2✔
103
}
104
END_TEST
1✔
105

106
START_TEST (table_add_test) {
1✔
107
  int res;
108
  pr_table_t *tab;
109

110
  res = pr_table_add(NULL, NULL, NULL, 0);
1✔
111
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
112
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
113

114
  tab = pr_table_alloc(p, 0);
1✔
115
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
2✔
116

117
  res = pr_table_add(tab, NULL, NULL, 0);
1✔
118
  ck_assert_msg(res == -1, "Failed to handle null key");
2✔
119
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
120

121
  res = pr_table_add(tab, "", NULL, 0);
1✔
122
  ck_assert_msg(res == 0, "Failed to add null value (len 0) for empty key");
2✔
123

124
  res = pr_table_add(tab, "", NULL, 1);
1✔
125
  ck_assert_msg(res == -1, "Failed to handle null value (len 1) for empty key");
2✔
126
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
127

128
  res = pr_table_add(tab, "", NULL, 0);
1✔
129
  ck_assert_msg(res == -1, "Failed to handle duplicate (empty) key");
2✔
130
  ck_assert_msg(errno == EEXIST, "Failed to set errno to EEXIST");
2✔
131
}
132
END_TEST
1✔
133

134
START_TEST (table_add_dup_test) {
1✔
135
  int res;
136
  pr_table_t *tab;
137

138
  res = pr_table_add_dup(NULL, NULL, NULL, 0);
1✔
139
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
140
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
141

142
  tab = pr_table_alloc(p, 0);
1✔
143
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
2✔
144

145
  res = pr_table_add_dup(tab, NULL, NULL, 0);
1✔
146
  ck_assert_msg(res == -1, "Failed to handle null key");
2✔
147
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
148

149
  res = pr_table_add_dup(tab, "", NULL, 0);
1✔
150
  ck_assert_msg(res == 0, "Failed to add null value (len 0) for empty key");
2✔
151

152
  res = pr_table_add_dup(tab, "", NULL, 1);
1✔
153
  ck_assert_msg(res == -1, "Failed to handle null value (len 1) for empty key");
2✔
154
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
155

156
  res = pr_table_add_dup(tab, "", NULL, 0);
1✔
157
  ck_assert_msg(res == 0, "Failed to handle empty value: %s", strerror(errno));
2✔
158

159
  mark_point();
1✔
160
  res = pr_table_add_dup(tab, "foo", "bar", 0);
1✔
161
  ck_assert_msg(res == 0, "Failed to add 'foo': %s", strerror(errno));
2✔
162
}
163
END_TEST
1✔
164

165
START_TEST (table_count_test) {
1✔
166
  int res, ok;
167
  pr_table_t *tab;
168

169
  res = pr_table_count(NULL);
1✔
170
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
171
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
172

173
  tab = pr_table_alloc(p, 0);
1✔
174

175
  ok = 0;
1✔
176
  res = pr_table_count(tab);
1✔
177
  ck_assert_msg(res == ok, "Expected count %d, got %d", ok, res);
2✔
178

179
  res = pr_table_add(tab, "foo", NULL, 0);
1✔
180
  ck_assert_msg(res == 0, "Failed to add item to table: %s", strerror(errno));
2✔
181

182
  ok = 1;
1✔
183
  res = pr_table_count(tab);
1✔
184
  ck_assert_msg(res == ok, "Expected count %d, got %d", ok, res);
2✔
185

186
  res = pr_table_add(tab, "bar", NULL, 0);
1✔
187
  ck_assert_msg(res == 0, "Failed to add item to table: %s", strerror(errno));
2✔
188

189
  ok = 2;
1✔
190
  res = pr_table_count(tab);
1✔
191
  ck_assert_msg(res == ok, "Expected count %d, got %d", ok, res);
2✔
192
}
193
END_TEST
1✔
194

195
START_TEST (table_exists_test) {
1✔
196
  int res, ok;
197
  pr_table_t *tab;
198

199
  res = pr_table_exists(NULL, NULL);
1✔
200
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
201
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
202

203
  tab = pr_table_alloc(p, PR_TABLE_FL_MULTI_VALUE);
1✔
204
  ck_assert_msg(tab != NULL, "Failed to allocate table: %s", strerror(errno));
2✔
205

206
  res = pr_table_exists(tab, NULL);
1✔
207
  ck_assert_msg(res == -1, "Failed to handle null key");
2✔
208
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
209

210
  res = pr_table_exists(NULL, "foo");
1✔
211
  ck_assert_msg(res == -1, "Failed to handle null table");
2✔
212
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
213

214
  ok = -1;
1✔
215
  res = pr_table_exists(tab, "foo");
1✔
216
  ck_assert_msg(res == ok, "Expected value count %d, got %d", ok, res);
2✔
217
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
2✔
218

219
  res = pr_table_add(tab, "foo", "a", 0);
1✔
220
  ck_assert_msg(res == 0, "Failed to add key to table: %s", strerror(errno));
2✔
221

222
  ok = 1;
1✔
223
  res = pr_table_exists(tab, "foo");
1✔
224
  ck_assert_msg(res == ok, "Expected value count %d, got %d", ok, res);
2✔
225

226
  res = pr_table_add(tab, "foo", "b", 0);
1✔
227
  ck_assert_msg(res == 0, "Failed to add key to table: %s", strerror(errno));
2✔
228

229
  ok = 2;
1✔
230
  res = pr_table_exists(tab, "foo");
1✔
231
  ck_assert_msg(res == ok, "Expected value count %d, got %d", ok, res);
2✔
232

233
  mark_point();
1✔
234
  res = pr_table_kexists(NULL, NULL, 0);
1✔
235
  ck_assert_msg(res < 0, "Failed to handle null table");
2✔
236
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
237
    strerror(errno), errno);
238

239
  mark_point();
1✔
240
  res = pr_table_kexists(tab, NULL, 0);
1✔
241
  ck_assert_msg(res < 0, "Failed to handle null key_data");
2✔
242
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
243
    strerror(errno), errno);
244
}
245
END_TEST
1✔
246

247
START_TEST (table_empty_test) {
1✔
248
  int res;
249
  pr_table_t *tab;
250

251
  res = pr_table_empty(NULL);
1✔
252
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
253
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
254

255
  tab = pr_table_alloc(p, 0);
1✔
256

257
  res = pr_table_empty(tab);
1✔
258
  ck_assert_msg(res == 0, "Failed to empty table: %s", strerror(errno));
2✔
259

260
  res = pr_table_add(tab, "foo", NULL, 0);
1✔
261
  ck_assert_msg(res == 0, "Failed to add key to table: %s", strerror(errno));
2✔
262

263
  res = pr_table_count(tab);
1✔
264
  ck_assert_msg(res == 1, "Expected table item count of 1, got %d", res);
2✔
265

266
  res = pr_table_empty(tab);
1✔
267
  ck_assert_msg(res == 0, "Failed to empty table: %s", strerror(errno));
2✔
268

269
  res = pr_table_count(tab);
1✔
270
  ck_assert_msg(res == 0, "Expected table item count of 0, got %d", res);
2✔
271
}
272
END_TEST
1✔
273

274
START_TEST (table_free_test) {
1✔
275
  int res;
276
  pr_table_t *tab;
277

278
  res = pr_table_free(NULL);
1✔
279
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
280
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
281

282
  tab = pr_table_alloc(p, 0);
1✔
283

284
  res = pr_table_free(tab);
1✔
285
  ck_assert_msg(res == 0, "Failed to free table: %s", strerror(errno));
2✔
286

287
  tab = pr_table_alloc(p, 0);
1✔
288
  res = pr_table_add(tab, "foo", "bar", 0);
1✔
289
  ck_assert_msg(res == 0, "Failed to add item to table: %s", strerror(errno));
2✔
290

291
  res = pr_table_free(tab);
1✔
292
  ck_assert_msg(res == -1, "Failed to handle non-empty table");
2✔
293
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
2✔
294
}
295
END_TEST
1✔
296

297
START_TEST (table_get_test) {
1✔
298
  int ok, xerrno;
299
  const void *res;
300
  pr_table_t *tab;
301
  char *str;
302
  size_t sz;
303

304
  res = pr_table_get(NULL, NULL, NULL);
1✔
305
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
306
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
307

308
  tab = pr_table_alloc(p, 0);
1✔
309

310
  res = pr_table_get(tab, NULL, NULL);
1✔
311
  ck_assert_msg(res == NULL, "Failed to handle null key");
2✔
312
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
2✔
313

314
  ok = pr_table_add(tab, "foo", NULL, 0);
1✔
315
  ck_assert_msg(ok == 0, "Failed to add null value to table: %s",
2✔
316
    strerror(errno));
317

318
  errno = xerrno = 0;
1✔
319
  res = pr_table_get(tab, "foo", &sz);
1✔
320
  xerrno = errno;
1✔
321

322
  ck_assert_msg(res == NULL, "Failed to lookup null value: %s", strerror(errno));
2✔
323
  ck_assert_msg(xerrno == 0, "Expected errno 0, got %d (%s)", xerrno,
2✔
324
    strerror(xerrno));
325

326
  ok = pr_table_add(tab, "bar", "baz", 0);
1✔
327
  ck_assert_msg(ok == 0, "Failed to add 'bar' to table: %s", strerror(errno));
2✔
328

329
  res = pr_table_get(tab, "bar", &sz);
1✔
330
  ck_assert_msg(res != NULL, "Failed to lookup value for 'bar': %s",
2✔
331
    strerror(errno));
332
  ck_assert_msg(sz == 4, "Expected result len of 4, got %lu", (unsigned long)sz);
2✔
333

334
  str = pcalloc(p, sz);
1✔
335
  memcpy(str, res, sz);
2✔
336

337
  ck_assert_msg(strcmp(str, "baz") == 0,
2✔
338
    "Expected value '%s', got '%s'", "baz", str);
339

340
  mark_point();
1✔
341
  res = pr_table_kget(NULL, NULL, 0, NULL);
1✔
342
  ck_assert_msg(res == NULL, "Failed to handle null table");
2✔
343
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
344
    strerror(errno), errno);
345
}
346
END_TEST
1✔
347

348
static unsigned int cache_key_hash(const void *key, size_t keysz) {
3✔
349
  return 1;
3✔
350
}
351

352
START_TEST (table_get_use_cache_test) {
1✔
353
  int ok, xerrno;
354
  const void *res;
355
  pr_table_t *tab;
356
  const char *key = "bar";
1✔
357
  char *str;
358
  size_t sz;
359

360
  res = pr_table_get(NULL, NULL, NULL);
1✔
361
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
362
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
363

364
  tab = pr_table_alloc(p, PR_TABLE_FL_USE_CACHE);
1✔
365

366
  /* We use this specific key hash function to ensure that all of the keys we
367
   * add to this table end up in the same linked-list chain.
368
   */
369

370
  ok = pr_table_ctl(tab, PR_TABLE_CTL_SET_KEY_HASH, cache_key_hash);
1✔
371
  ck_assert_msg(ok == 0, "Failed to set key hash function for table: %s",
2✔
372
    strerror(errno));
373

374
  res = pr_table_get(tab, NULL, NULL);
1✔
375
  ck_assert_msg(res == NULL, "Failed to handle null key");
2✔
376
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
2✔
377

378
  ok = pr_table_add(tab, key, "baz", 0);
1✔
379
  ck_assert_msg(ok == 0, "Failed to add 'bar' to table: %s", strerror(errno));
2✔
380

381
  res = pr_table_get(tab, key, &sz);
1✔
382
  ck_assert_msg(res != NULL, "Failed to lookup value for 'bar': %s",
2✔
383
    strerror(errno));
384
  ck_assert_msg(sz == 4, "Expected result len of 4, got %lu", (unsigned long)sz);
2✔
385

386
  str = pcalloc(p, sz);
1✔
387
  memcpy(str, res, sz);
2✔
388

389
  ck_assert_msg(strcmp(str, "baz") == 0,
2✔
390
    "Expected value '%s', got '%s'", "baz", str);
391

392
  /* With the USE_CACHE flag on, we should still receive NULL here. */
393
  errno = xerrno = 0;
1✔
394
  res = pr_table_get(tab, key, &sz);
1✔
395
  ck_assert_msg(res == NULL, "Failed to return null next value: %s",
2✔
396
    strerror(errno));
397
  ck_assert_msg(xerrno == 0, "Expected errno 0, got %d (%s)", xerrno,
1✔
398
    strerror(xerrno));
399

400
}
401
END_TEST
1✔
402

403
START_TEST (table_next_test) {
1✔
404
  int ok;
405
  const char *res;
406
  size_t sz = 0;
1✔
407
  pr_table_t *tab;
408

409
  res = pr_table_next(NULL);
1✔
410
  ck_assert_msg(res == NULL, "Failed to handle null table");
1✔
411
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
412

413
  tab = pr_table_alloc(p, 0);
1✔
414

415
  res = pr_table_next(tab);
1✔
416
  ck_assert_msg(res == NULL, "Failed to handle empty table");
2✔
417
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
2✔
418

419
  ok = pr_table_add(tab, "foo", NULL, 0);
1✔
420
  ck_assert_msg(ok == 0, "Failed to add 'foo' to table: %s", strerror(errno));
2✔
421

422
  res = pr_table_next(tab);
1✔
423
  ck_assert_msg(res != NULL, "Failed to get next key: %s", strerror(errno));
2✔
424
  ck_assert_msg(strcmp(res, "foo") == 0,
2✔
425
    "Expected key '%s', got '%s'", "foo", res);
426

427
  res = pr_table_next(tab);
1✔
428
  ck_assert_msg(res == NULL, "Expected no more keys, got '%s'", res);
2✔
429

430
  pr_table_rewind(tab);
1✔
431

432
  res = pr_table_knext(tab, &sz);
1✔
433
  ck_assert_msg(res != NULL, "Failed to get next key: %s", strerror(errno));
2✔
434
  ck_assert_msg(sz == 4, "Expected 4, got %lu", (unsigned long) sz);
2✔
435
  ck_assert_msg(strcmp(res, "foo") == 0,
2✔
436
    "Expected key '%s', got '%s'", "foo", res);
437

438
  sz = 0;
1✔
439
  res = pr_table_knext(tab, &sz);
1✔
440
  ck_assert_msg(res == NULL, "Expected no more keys, got '%s'", res);
2✔
441
}
442
END_TEST
1✔
443

444
START_TEST (table_rewind_test) {
1✔
445
  int res;
446
  const char *key;
447
  pr_table_t *tab;
448

449
  res = pr_table_rewind(NULL);
1✔
450
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
451
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
452

453
  tab = pr_table_alloc(p, 0);
1✔
454

455
  res = pr_table_rewind(tab);
1✔
456
  ck_assert_msg(res == 0, "Failed to handle empty table");
2✔
457

458
  res = pr_table_add(tab, "foo", NULL, 0);
1✔
459
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
2✔
460

461
  key = pr_table_next(tab);
1✔
462
  ck_assert_msg(key != NULL, "Failed to get next key: %s", strerror(errno));
2✔
463
  ck_assert_msg(strcmp(key, "foo") == 0,
2✔
464
    "Expected key '%s', got '%s'", "foo", key);
465

466
  key = pr_table_next(tab);
1✔
467
  ck_assert_msg(key == NULL, "Expected no more keys, got '%s'", key);
2✔
468

469
  res = pr_table_rewind(tab);
1✔
470
  ck_assert_msg(res == 0, "Failed to rewind table: %s", strerror(errno));
2✔
471

472
  key = pr_table_next(tab);
1✔
473
  ck_assert_msg(key != NULL, "Failed to get next key: %s", strerror(errno));
2✔
474
  ck_assert_msg(strcmp(key, "foo") == 0,
2✔
475
    "Expected key '%s', got '%s'", "foo", key);
476

477
  key = pr_table_next(tab);
1✔
478
  ck_assert_msg(key == NULL, "Expected no more keys, got '%s'", key);
2✔
479
}
480
END_TEST
1✔
481

482
START_TEST (table_remove_test) {
1✔
483
  int ok;
484
  const char *res;
485
  char *str;
486
  pr_table_t *tab;
487
  size_t sz;
488

489
  res = pr_table_remove(NULL, NULL, NULL);
1✔
490
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
491
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
492

493
  tab = pr_table_alloc(p, 0);
1✔
494

495
  res = pr_table_remove(tab, NULL, 0);
1✔
496
  ck_assert_msg(res == NULL, "Failed to handle null key");
2✔
497
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
498

499
  res = pr_table_remove(tab, "foo", &sz);
1✔
500
  ck_assert_msg(res == NULL, "Failed to handle absent value");
2✔
501
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
2✔
502

503
  ok = pr_table_add(tab, "foo", "bar baz", 0);
1✔
504
  ck_assert_msg(ok == 0, "Failed to add key to table: %s", strerror(errno));
2✔
505

506
  res = pr_table_remove(tab, "foo", &sz);
1✔
507
  ck_assert_msg(res != NULL, "Failed to remove 'foo': %s", strerror(errno));
2✔
508
  ck_assert_msg(sz == 8, "Expected value len of 8, got %lu", (unsigned long)sz);
2✔
509

510
  str = pcalloc(p, sz);
1✔
511
  memcpy(str, res, sz);
2✔
512

513
  ck_assert_msg(strcmp(str, "bar baz") == 0,
2✔
514
    "Expected value of '%s', got '%s'", "bar baz", str);
515

516
  ok = pr_table_count(tab);
1✔
517
  ck_assert_msg(ok == 0, "Expected table count of 0, got %d", ok);
2✔
518

519
  res = pr_table_remove(tab, "foo", &sz);
1✔
520
  ck_assert_msg(res == NULL, "Failed to handle absent value");
2✔
521
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT");
2✔
522

523
  mark_point();
1✔
524
  res = pr_table_kremove(NULL, NULL, 0, NULL);
1✔
525
  ck_assert_msg(res == NULL, "Failed to handle null table");
2✔
526
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
527
    strerror(errno), errno);
528

529
  mark_point();
1✔
530
  res = pr_table_kremove(tab, NULL, 0, NULL);
1✔
531
  ck_assert_msg(res == NULL, "Failed to handle null key data");
2✔
532
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
533
    strerror(errno), errno);
534
}
535
END_TEST
1✔
536

537
START_TEST (table_set_test) {
1✔
538
  int res;
539
  pr_table_t *tab;
540
  const void *v;
541
  char *str;
542
  size_t sz;
543

544
  res = pr_table_set(NULL, NULL, NULL, 0);
1✔
545
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
546
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
547

548
  tab = pr_table_alloc(p, 0);
1✔
549

550
  res = pr_table_set(tab, NULL, NULL, 0);
1✔
551
  ck_assert_msg(res == -1, "Failed to handle null key");
2✔
552
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
553

554
  res = pr_table_set(tab, "foo", NULL, 1);
1✔
555
  ck_assert_msg(res == -1, "Failed to handle null value (len 1)");
2✔
556
  ck_assert_msg(errno == EINVAL, "Failed to handle null value (len 1)");
2✔
557

558
  mark_point();
1✔
559
  res = pr_table_set(tab, "foo", "bar", 1);
1✔
560
  ck_assert_msg(res < 0, "Failed to handle empty table");
2✔
561
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
2✔
562
    strerror(errno), errno);
563

564
  res = pr_table_add(tab, "foo", "bar", 0);
1✔
565
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
2✔
566

567
  res = pr_table_set(tab, "foo", "BAZ", 0);
1✔
568
  ck_assert_msg(res == 0, "Failed to set 'foo' in table: %s", strerror(errno));
2✔
569

570
  v = pr_table_get(tab, "foo", &sz);
1✔
571
  ck_assert_msg(v != NULL, "Failed to retrieve 'foo' from table: %s",
2✔
572
    strerror(errno));
573
  ck_assert_msg(sz == 4, "Expected len 4, got %lu", (unsigned long)sz);
2✔
574

575
  str = pcalloc(p, sz);
1✔
576
  memcpy(str, v, sz);
2✔
577

578
  ck_assert_msg(strcmp(str, "BAZ") == 0,
2✔
579
    "Expected value of '%s', got '%s'", "BAZ", str);
580
}
581
END_TEST
1✔
582

583
START_TEST (table_do_test) {
1✔
584
  int res;
585
  pr_table_t *tab;
586

587
  res = pr_table_do(NULL, NULL, NULL, 0);
1✔
588
  ck_assert_msg(res == -1, "Failed to handle null arguments");
1✔
589
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
590

591
  tab = pr_table_alloc(p, 0);
1✔
592

593
  res = pr_table_do(tab, NULL, NULL, 0);
1✔
594
  ck_assert_msg(res == -1, "Failed to handle null arguments");
2✔
595
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
596

597
  res = pr_table_do(tab, do_cb, NULL, 0);
1✔
598
  ck_assert_msg(res == 0, "Failed to handle empty table");
2✔
599

600
  res = pr_table_add(tab, "foo", "bar", 0);
1✔
601
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
2✔
602

603
  res = pr_table_add(tab, "bar", "baz", 0);
1✔
604
  ck_assert_msg(res == 0, "Failed to add 'bar' to table: %s", strerror(errno));
2✔
605

606
  res = pr_table_do(tab, do_cb, NULL, 0);
1✔
607
  ck_assert_msg(res == -1, "Expected res %d, got %d", -1, res);
2✔
608
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
2✔
609
  ck_assert_msg(b_val_count == 1, "Expected count %u, got %u", 1, b_val_count);
2✔
610

611
  b_val_count = 0;
1✔
612
  res = pr_table_do(tab, do_cb, NULL, PR_TABLE_DO_FL_ALL);
1✔
613
  ck_assert_msg(res == 0, "Failed to do table: %s", strerror(errno));
2✔
614
  ck_assert_msg(b_val_count == 2, "Expected count %u, got %u", 2, b_val_count);
2✔
615
}
616
END_TEST
1✔
617

618
START_TEST (table_do_with_remove_test) {
1✔
619
  int res;
620
  pr_table_t *tab;
621

622
  tab = pr_table_alloc(p, 0);
1✔
623

624
  res = pr_table_add(tab, "foo", "bar", 0);
1✔
625
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
1✔
626

627
  res = pr_table_add(tab, "bar", "baz", 0);
1✔
628
  ck_assert_msg(res == 0, "Failed to add 'bar' to table: %s", strerror(errno));
2✔
629

630
  b_val_count = 0;
1✔
631
  res = pr_table_do(tab, do_with_remove_cb, tab, PR_TABLE_DO_FL_ALL);
1✔
632
  ck_assert_msg(res == 0, "Failed to do table: %s", strerror(errno));
2✔
633
  ck_assert_msg(b_val_count == 2, "Expected count %u, got %u", 2, b_val_count);
2✔
634
}
635
END_TEST
1✔
636

637
START_TEST (table_ctl_test) {
1✔
638
  int res;
639
  pr_table_t *tab;
640
  unsigned long flags = 0;
1✔
641
  unsigned int max_ents = 0, nchains = 0;
1✔
642

643
  res = pr_table_ctl(NULL, 0, NULL);
1✔
644
  ck_assert_msg(res == -1, "Failed to handle null table");
1✔
645
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
646

647
  tab = pr_table_alloc(p, 0);
1✔
648

649
  mark_point();
1✔
650
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_ENT_INSERT, NULL);
1✔
651
  ck_assert_msg(res == 0, "Failed to set entry insert callback: %s",
2✔
652
    strerror(errno));
653

654
  mark_point();
1✔
655
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_ENT_REMOVE, NULL);
1✔
656
  ck_assert_msg(res == 0, "Failed to set entry removal callback: %s",
2✔
657
    strerror(errno));
658

659
  res = pr_table_add(tab, "foo", "bar", 0);
1✔
660
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
2✔
661

662
  mark_point();
1✔
663
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, 0);
1✔
664
  ck_assert_msg(res < 0, "Failed to handle SET_MAX_ENTS smaller than table");
2✔
665
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2✔
666
    strerror(errno), errno);
667

668
  res = pr_table_ctl(tab, 0, NULL);
1✔
669
  ck_assert_msg(res == -1, "Failed to handle non-empty table");
2✔
670
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
2✔
671

672
  res = pr_table_empty(tab);
1✔
673
  ck_assert_msg(res == 0, "Failed to empty table: %s", strerror(errno));
2✔
674

675
  res = pr_table_ctl(tab, 0, NULL);
1✔
676
  ck_assert_msg(res == -1, "Failed to handle unknown ctl");
2✔
677
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
678

679
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_FLAGS, NULL);
1✔
680
  ck_assert_msg(res == -1, "Failed to handle SET_FLAGS, null args");
2✔
681
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
682

683
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_FLAGS, &flags);
1✔
684
  ck_assert_msg(res == 0, "Failed to handle SET_FLAGS: %s", strerror(errno));
2✔
685

686
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, NULL);
1✔
687
  ck_assert_msg(res == -1, "Failed to handle SET_NCHAINS, null args");
2✔
688
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
689

690
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, &nchains);
1✔
691
  ck_assert_msg(res == -1, "Failed to handle SET_NCHAINS, zero args");
2✔
692
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
693

694
  nchains = 1;
1✔
695
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_NCHAINS, &nchains);
1✔
696
  ck_assert_msg(res == 0, "Failed to handle SET_NCHAINS: %s", strerror(errno));
2✔
697

698
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
1✔
699
  ck_assert_msg(res == -1, "Failed to handle SET_MAX_ENTS, zero args");
2✔
700
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
701

702
  /* Add two entries, then try to set MAX_ENTS to one.  We should get an
703
   * EPERM back for that.
704
   */
705
  res = pr_table_add(tab, "foo", "bar", 0);
1✔
706
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
2✔
707

708
  res = pr_table_add(tab, "baz", "quxx", 0);
1✔
709
  ck_assert_msg(res == 0, "Failed to add 'baz' to table: %s", strerror(errno));
2✔
710

711
  max_ents = 1;
1✔
712
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
1✔
713
  ck_assert_msg(res == -1, "Failed to handle SET_MAX_ENTS on non-empty table");
2✔
714
  ck_assert_msg(errno == EPERM, "Failed to set errno to EPERM");
2✔
715

716
  /* Now empty the table, set the MAX_ENTS to one, then try add two entries. */
717

718
  res = pr_table_empty(tab);
1✔
719
  ck_assert_msg(res == 0, "Failed to empty table: %s", strerror(errno));
2✔
720

721
  max_ents = 1;
1✔
722
  res = pr_table_ctl(tab, PR_TABLE_CTL_SET_MAX_ENTS, &max_ents);
1✔
723
  ck_assert_msg(res == 0, "Failed to handle SET_MAX_ENTS to %d: %s",
2✔
724
    max_ents, strerror(errno));
725

726
  res = pr_table_add(tab, "foo", "bar", 0);
1✔
727
  ck_assert_msg(res == 0, "Failed to add 'foo' to table: %s", strerror(errno));
2✔
728

729
  res = pr_table_add(tab, "baz", "quxx", 0);
1✔
730
  ck_assert_msg(res == -1, "Added second entry unexpectedly");
2✔
731
  ck_assert_msg(errno == ENOSPC,
2✔
732
    "Failed to set errno to ENOSPC, received %d (%s)", errno, strerror(errno));
733
}
734
END_TEST
1✔
735

736
START_TEST (table_load_test) {
1✔
737
  pr_table_t *tab = NULL;
1✔
738
  float load;
739

740
  load = pr_table_load(tab);
1✔
741
  ck_assert_msg(load < 0, "Failed to handle NULL table argument");
1✔
742
  ck_assert_msg(errno == EINVAL,
2✔
743
    "Failed to set errno to EINVAL; received %d (%s)", errno, strerror(errno));
744

745
  tab = pr_table_alloc(p, 0);
1✔
746
  load = pr_table_load(tab);
1✔
747
  ck_assert_msg(load >= 0.0, "Failed to calculate load properly; load = %0.3f",
2✔
748
    load);
749
}
750
END_TEST
1✔
751

752
START_TEST (table_dump_test) {
1✔
753
  pr_table_t *tab;
754

755
  pr_table_dump(NULL, NULL);
1✔
756

757
  tab = pr_table_alloc(p, 0);
1✔
758

759
  pr_table_dump(NULL, tab);
1✔
760
  pr_table_dump(table_dump, NULL);
1✔
761
}
762
END_TEST
1✔
763

764
START_TEST (table_pcalloc_test) {
1✔
765
  void *res;
766
  pr_table_t *tab;
767

768
  res = pr_table_pcalloc(NULL, 0);
1✔
769
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
770
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
771

772
  tab = pr_table_alloc(p, 0);
1✔
773

774
  res = pr_table_pcalloc(tab, 0);
1✔
775
  ck_assert_msg(res == NULL, "Failed to handle zero len argument");
2✔
776
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
777

778
  res = pr_table_pcalloc(NULL, 1);
1✔
779
  ck_assert_msg(res == NULL, "Failed to handle null table");
2✔
780
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL");
2✔
781

782
  res = pr_table_pcalloc(tab, 2);
1✔
783
  ck_assert_msg(res != NULL, "Failed to allocate len 2 from table: %s",
2✔
784
    strerror(errno));
785
}
786
END_TEST
1✔
787

788
Suite *tests_get_table_suite(void) {
917✔
789
  Suite *suite;
790
  TCase *testcase;
791

792
  suite = suite_create("table");
917✔
793
  testcase = tcase_create("base");
917✔
794

795
  tcase_add_checked_fixture(testcase, set_up, tear_down);
917✔
796

797
  tcase_add_test(testcase, table_alloc_test);
917✔
798
  tcase_add_test(testcase, table_nalloc_test);
917✔
799
  tcase_add_test(testcase, table_add_test);
917✔
800
  tcase_add_test(testcase, table_add_dup_test);
917✔
801
  tcase_add_test(testcase, table_count_test);
917✔
802
  tcase_add_test(testcase, table_exists_test);
917✔
803
  tcase_add_test(testcase, table_empty_test);
917✔
804
  tcase_add_test(testcase, table_free_test);
917✔
805
  tcase_add_test(testcase, table_get_test);
917✔
806
  tcase_add_test(testcase, table_get_use_cache_test);
917✔
807
  tcase_add_test(testcase, table_next_test);
917✔
808
  tcase_add_test(testcase, table_rewind_test);
917✔
809
  tcase_add_test(testcase, table_remove_test);
917✔
810
  tcase_add_test(testcase, table_set_test);
917✔
811
  tcase_add_test(testcase, table_do_test);
917✔
812
  tcase_add_test(testcase, table_do_with_remove_test);
917✔
813
  tcase_add_test(testcase, table_ctl_test);
917✔
814
  tcase_add_test(testcase, table_load_test);
917✔
815
  tcase_add_test(testcase, table_dump_test);
917✔
816
  tcase_add_test(testcase, table_pcalloc_test);
917✔
817

818
  suite_add_tcase(suite, testcase);
917✔
819
  return suite;
917✔
820
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc