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

proftpd / proftpd / 26127302554

19 May 2026 07:34PM UTC coverage: 92.635% (-0.4%) from 93.024%
26127302554

push

github

Castaglia
Make a flaky, racy mod_copy regression test more reliable.

47303 of 51064 relevant lines covered (92.63%)

241.07 hits per line

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

97.53
/tests/api/data.c
1
/*
2
 * ProFTPD - FTP server testsuite
3
 * Copyright (c) 2015-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
/* Data API tests */
25

26
#include "tests.h"
27

28
static pool *p = NULL;
29

30
static const char *data_test_path = "/tmp/prt-data.dat";
31

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

37
  init_fs();
20✔
38
  init_netio();
20✔
39
  init_config();
20✔
40
  init_dirtree();
20✔
41

42
  pr_parser_prepare(p, NULL);
20✔
43

44
  pr_response_set_pool(p);
20✔
45
  (void) pr_fsio_unlink(data_test_path);
20✔
46

47
  if (session.c != NULL) {
20✔
48
    pr_inet_close(p, session.c);
×
49
    session.c = NULL;
×
50
  }
51

52
  session.sf_flags = 0;
20✔
53

54
  pr_trace_set_levels("timing", 1, 1);
20✔
55
  if (getenv("TEST_VERBOSE") != NULL) {
20✔
56
    pr_trace_set_levels("data", 1, 20);
20✔
57
  }
58
}
20✔
59

60
static void tear_down(void) {
20✔
61
  (void) pr_fsio_unlink(data_test_path);
20✔
62

63
  if (session.c != NULL) {
20✔
64
    (void) pr_inet_close(p, session.c);
6✔
65
  }
66

67
  if (session.d != NULL &&
26✔
68
      session.d != session.c) {
6✔
69
    (void) pr_inet_close(p, session.d);
6✔
70
  }
71

72
  session.c = session.d = NULL;
20✔
73

74
  pr_unregister_netio(PR_NETIO_STRM_CTRL|PR_NETIO_STRM_CTRL);
20✔
75
  pr_unregister_netio(PR_NETIO_STRM_CTRL|PR_NETIO_STRM_DATA);
20✔
76

77
  if (getenv("TEST_VERBOSE") != NULL) {
20✔
78
    pr_trace_set_levels("data", 0, 0);
20✔
79
  }
80
  pr_trace_set_levels("timing", 0, 0);
20✔
81

82
  pr_parser_cleanup();
20✔
83
  pr_response_set_pool(NULL);
20✔
84

85
  if (p == NULL) {
20✔
86
    destroy_pool(p);
×
87
    p = session.pool = session.xfer.p = permanent_pool = NULL;
×
88
  }
89
}
20✔
90

91
static int tmpfile_fd(void) {
1✔
92
  int fd;
93

94
  fd = open(data_test_path, O_CREAT|O_RDWR, 0600);
2✔
95
  if (fd < 0) {
1✔
96
    fprintf(stderr, "Error opening %s: %s\n", data_test_path, strerror(errno));
×
97
    return -1;
×
98
  }
99

100
  (void) unlink(data_test_path);
1✔
101
  return fd;
1✔
102
}
103

104
static int rewind_fd(int fd) {
105
  if (lseek(fd, 0, SEEK_SET) == (off_t) -1) {
1✔
106
    return -1;
107
  }
108

109
  return 0;
110
}
111

112
START_TEST (data_get_timeout_test) {
1✔
113
  int res;
114

115
  res = pr_data_get_timeout(-1);
1✔
116
  ck_assert_msg(res < 0, "Failed to handle invalid timeout ID");
1✔
117
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
118
    strerror(errno), errno);
119

120
  res = pr_data_get_timeout(PR_DATA_TIMEOUT_IDLE);
1✔
121
  ck_assert_msg(res == PR_TUNABLE_TIMEOUTIDLE, "Expected %d, got %d",
2✔
122
    PR_TUNABLE_TIMEOUTIDLE, res);
123

124
  res = pr_data_get_timeout(PR_DATA_TIMEOUT_NO_TRANSFER);
1✔
125
  ck_assert_msg(res == PR_TUNABLE_TIMEOUTNOXFER, "Expected %d, got %d",
2✔
126
    PR_TUNABLE_TIMEOUTNOXFER, res);
127

128
  res = pr_data_get_timeout(PR_DATA_TIMEOUT_STALLED);
1✔
129
  ck_assert_msg(res == PR_TUNABLE_TIMEOUTSTALLED, "Expected %d, got %d",
2✔
130
    PR_TUNABLE_TIMEOUTSTALLED, res);
131
}
132
END_TEST
1✔
133

134
START_TEST (data_set_timeout_test) {
1✔
135
  int res, timeout = 7;
1✔
136

137
  pr_data_set_timeout(PR_DATA_TIMEOUT_IDLE, timeout);
1✔
138
  res = pr_data_get_timeout(PR_DATA_TIMEOUT_IDLE);
1✔
139
  ck_assert_msg(res == timeout, "Expected %d, got %d", timeout, res);
1✔
140

141
  pr_data_set_timeout(PR_DATA_TIMEOUT_NO_TRANSFER, timeout);
1✔
142
  res = pr_data_get_timeout(PR_DATA_TIMEOUT_NO_TRANSFER);
1✔
143
  ck_assert_msg(res == timeout, "Expected %d, got %d", timeout, res);
2✔
144

145
  pr_data_set_timeout(PR_DATA_TIMEOUT_STALLED, timeout);
1✔
146
  res = pr_data_get_timeout(PR_DATA_TIMEOUT_STALLED);
1✔
147
  ck_assert_msg(res == timeout, "Expected %d, got %d", timeout, res);
2✔
148

149
  /* Interestingly, the linger timeout has its own function. */
150
  pr_data_set_linger(7L);
1✔
151
}
152
END_TEST
1✔
153

154
START_TEST (data_ignore_ascii_test) {
1✔
155
  int res;
156

157
  res = pr_data_ignore_ascii(-1);
1✔
158
  ck_assert_msg(res < 0, "Failed to handle invalid argument");
1✔
159
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
160
    strerror(errno), errno);
161

162
  res = pr_data_ignore_ascii(TRUE);
1✔
163
  ck_assert_msg(res == FALSE, "Expected FALSE (%d), got %d", FALSE, res);
2✔
164

165
  res = pr_data_ignore_ascii(TRUE);
1✔
166
  ck_assert_msg(res == TRUE, "Expected TRUE (%d), got %d", TRUE, res);
2✔
167

168
  res = pr_data_ignore_ascii(FALSE);
1✔
169
  ck_assert_msg(res == TRUE, "Expected TRUE (%d), got %d", TRUE, res);
2✔
170

171
  res = pr_data_ignore_ascii(FALSE);
1✔
172
  ck_assert_msg(res == FALSE, "Expected FALSE (%d), got %d", FALSE, res);
2✔
173
}
174
END_TEST
1✔
175

176
static int data_close_cb(pr_netio_stream_t *nstrm) {
30✔
177
  return 0;
30✔
178
}
179

180
static int data_poll_cb(pr_netio_stream_t *nstrm) {
46✔
181
  /* Always return >0, to indicate that we haven't timed out, AND that there
182
   * is a writable fd available.
183
   */
184
  return 7;
46✔
185
}
186

187
static int data_read_eagain = FALSE;
188
static int data_read_epipe = FALSE;
189
static int data_read_dangling_cr = FALSE;
190

191
static int data_read_cb(pr_netio_stream_t *nstrm, char *buf, size_t buflen) {
11✔
192
  const char *data = "Hello,\r\n World!\r\n";
11✔
193
  size_t sz;
194

195
  if (data_read_eagain) {
11✔
196
    data_read_eagain = FALSE;
1✔
197
    errno = EAGAIN;
1✔
198
    return -1;
1✔
199
  }
200

201
  if (data_read_epipe) {
10✔
202
    data_read_epipe = FALSE;
×
203
    errno = EPIPE;
×
204
    return -1;
×
205
  }
206

207
  if (data_read_dangling_cr) {
10✔
208
    data = "Hello,\r\n World!\r\n\r";
1✔
209
  }
210

211
  sz = strlen(data);
10✔
212
  if (buflen < sz) {
10✔
213
    sz = buflen;
×
214
  }
215

216
  memcpy(buf, data, sz);
10✔
217
  return (int) sz;
10✔
218
}
219

220
static int data_write_eagain = FALSE;
221
static int data_write_epipe = FALSE;
222

223
static int data_write_cb(pr_netio_stream_t *nstrm, char *buf, size_t buflen) {
21✔
224
  if (data_write_eagain) {
21✔
225
    data_write_eagain = FALSE;
5✔
226
    errno = EAGAIN;
5✔
227
    return -1;
5✔
228
  }
229

230
  if (data_write_epipe) {
16✔
231
    data_write_epipe = FALSE;
×
232
    errno = EPIPE;
×
233
    return -1;
×
234
  }
235

236
  return buflen;
16✔
237
}
238

239
static int data_open_streams(conn_t *conn, int strm_type) {
15✔
240
  int fd = 2, res;
15✔
241
  pr_netio_t *netio;
242
  pr_netio_stream_t *nstrm;
243

244
  netio = pr_alloc_netio2(p, NULL, "testsuite");
15✔
245
  netio->close = data_close_cb;
15✔
246
  netio->poll = data_poll_cb;
15✔
247
  netio->read = data_read_cb;
15✔
248
  netio->write = data_write_cb;
15✔
249

250
  res = pr_register_netio(netio, strm_type);
15✔
251
  if (res < 0) {
15✔
252
    return -1;
253
  }
254

255
  nstrm = pr_netio_open(p, strm_type, fd, PR_NETIO_IO_WR);
15✔
256
  if (nstrm == NULL) {
15✔
257
    return -1;
258
  }
259

260
  conn->outstrm = nstrm;
15✔
261

262
  nstrm = pr_netio_open(p, strm_type, fd, PR_NETIO_IO_RD);
15✔
263
  if (nstrm == NULL) {
15✔
264
    return -1;
265
  }
266

267
  conn->instrm = nstrm;
15✔
268
  return 0;
269
}
270

271
START_TEST (data_sendfile_test) {
1✔
272
  int fd = -1, res;
1✔
273
  off_t offset = 0;
1✔
274
  pr_fh_t *fh;
275
  const char *text;
276

277
  res = (int) pr_data_sendfile(fd, NULL, 0);
1✔
278
  if (res < 0 &&
2✔
279
      errno == ENOSYS) {
1✔
280
    return;
×
281
  }
282

283
  res = pr_data_sendfile(fd, NULL, 0);
1✔
284
  ck_assert_msg(res < 0, "Failed to handle null offset");
1✔
285
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
286
    strerror(errno), errno);
287

288
  res = pr_data_sendfile(fd, &offset, 0);
1✔
289
  ck_assert_msg(res < 0, "Failed to handle zero count");
2✔
290
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
291
    strerror(errno), errno);
292

293
  session.xfer.direction = PR_NETIO_IO_RD;
1✔
294
  res = pr_data_sendfile(fd, &offset, 1);
1✔
295
  ck_assert_msg(res < 0, "Failed to handle invalid transfer direction");
2✔
296
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2✔
297
    strerror(errno), errno);
298

299
  session.xfer.direction = PR_NETIO_IO_WR;
1✔
300
  res = pr_data_sendfile(fd, &offset, 1);
1✔
301
  ck_assert_msg(res < 0, "Failed to handle lack of data connection");
2✔
302
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2✔
303
    strerror(errno), errno);
304

305
  mark_point();
1✔
306
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
307
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
308

309
  res = data_open_streams(session.d, PR_NETIO_STRM_DATA);
1✔
310
  ck_assert_msg(res == 0, "Failed to open streams: %s", strerror(errno));
2✔
311

312
  mark_point();
1✔
313
  res = pr_data_sendfile(fd, &offset, 1);
1✔
314
  ck_assert_msg(res < 0, "Failed to handle bad file descriptor");
2✔
315
  ck_assert_msg(errno == EBADF || errno == EINVAL,
2✔
316
    "Expected EBADF (%d) or EINVAL (%d), got %s (%d)", EBADF, EINVAL,
317
    strerror(errno), errno);
318

319
  fh = pr_fsio_open(data_test_path, O_CREAT|O_EXCL|O_WRONLY);
1✔
320
  ck_assert_msg(fh != NULL, "Failed to open '%s': %s", data_test_path,
2✔
321
    strerror(errno));
322

323
  text = "Hello, World!\n";
1✔
324
  res = pr_fsio_write(fh, text, strlen(text));
1✔
325
  ck_assert_msg(res >= 0, "Failed to write to '%s': %s", data_test_path,
2✔
326
    strerror(errno));
327
  res = pr_fsio_close(fh);
1✔
328
  ck_assert_msg(res == 0, "Failed to close '%s': %s", data_test_path,
2✔
329
    strerror(errno));
330

331
  fd = open(data_test_path, O_RDONLY);
2✔
332
  ck_assert_msg(fd >= 0, "Failed to open '%s': %s", data_test_path,
2✔
333
    strerror(errno));
334

335
  mark_point();
1✔
336
  res = pr_data_sendfile(fd, &offset, strlen(text));
1✔
337
  if (res < 0) {
1✔
338
    ck_assert_msg(errno == ENOTSOCK || errno == EINVAL,
×
339
     "Expected ENOTSOCK (%d) or EINVAL (%d), got %s (%d)", ENOTSOCK, EINVAL,
340
     strerror(errno), errno);
341
  }
342

343
  (void) close(fd);
1✔
344
  (void) pr_netio_close(session.d->outstrm);
1✔
345
  session.d->outstrm = NULL;
1✔
346
  (void) pr_inet_close(p, session.d);
1✔
347
  session.d = NULL;
1✔
348

349
  pr_unregister_netio(PR_NETIO_STRM_DATA);
1✔
350
}
351
END_TEST
352

353
START_TEST (data_init_test) {
1✔
354
  int rd = PR_NETIO_IO_RD, wr = PR_NETIO_IO_WR;
1✔
355
  char *filename = NULL;
1✔
356

357
  mark_point();
1✔
358
  pr_data_init(filename, 0);
1✔
359
  ck_assert_msg(session.xfer.direction == 0, "Expected xfer direction %d, got %d",
1✔
360
    0, session.xfer.direction);
361
  ck_assert_msg(session.xfer.p != NULL, "Transfer pool not created as expected");
2✔
362
  ck_assert_msg(session.xfer.filename == NULL, "Expected null filename, got %s",
2✔
363
    session.xfer.filename);
364

365
  filename = "test.dat";
1✔
366
  pr_data_clear_xfer_pool();
1✔
367

368
  mark_point();
1✔
369
  pr_data_init(filename, rd);
1✔
370
  ck_assert_msg(session.xfer.direction == rd,
2✔
371
    "Expected xfer direction %d, got %d", rd, session.xfer.direction);
372
  ck_assert_msg(session.xfer.p != NULL, "Transfer pool not created as expected");
2✔
373
  ck_assert_msg(session.xfer.filename != NULL, "Missing transfer filename");
2✔
374
  ck_assert_msg(strcmp(session.xfer.filename, filename) == 0,
2✔
375
    "Expected '%s', got '%s'", filename, session.xfer.filename);
376

377
  mark_point();
1✔
378
  pr_data_init("test2.dat", wr);
1✔
379
  ck_assert_msg(session.xfer.direction == wr,
2✔
380
    "Expected xfer direction %d, got %d", wr, session.xfer.direction);
381
  ck_assert_msg(session.xfer.p != NULL, "Transfer pool not created as expected");
2✔
382
  ck_assert_msg(session.xfer.filename != NULL, "Missing transfer filename");
2✔
383

384
  /* Even though we opened with a new filename, the previous filename should
385
   * still be there, as we didn't actually clear/reset this transfer.
386
   */
387
  ck_assert_msg(strcmp(session.xfer.filename, filename) == 0,
2✔
388
    "Expected '%s', got '%s'", filename, session.xfer.filename);
389
}
390
END_TEST
1✔
391

392
START_TEST (data_open_active_test) {
1✔
393
  int dir = PR_NETIO_IO_RD, port = INPORT_ANY, sockfd = -1, res;
1✔
394
  conn_t *conn;
395

396
  mark_point();
1✔
397
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
398
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
399
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
400
    strerror(errno), errno);
401

402
  conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
1✔
403
  ck_assert_msg(conn != NULL, "Failed to create conn: %s", strerror(errno));
2✔
404

405
  /* Note: these tests REQUIRE that session.c be non-NULL */
406
  session.c = conn;
1✔
407

408
  /* Open a READing data transfer connection...*/
409

410
  mark_point();
1✔
411
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
412
  ck_assert_msg(res < 0, "Failed to handle null arguments");
2✔
413
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
414
    strerror(errno), errno);
415

416
  /* Note: we also need session.c to have valid local/remote_addr, too! */
417
  session.c->local_addr = session.c->remote_addr = pr_netaddr_get_addr(p, "127.0.0.1", NULL);
1✔
418
  ck_assert_msg(session.c->remote_addr != NULL, "Failed to get address: %s",
2✔
419
    strerror(errno));
420

421
  mark_point();
1✔
422
  session.d = session.c;
1✔
423
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
424
  ck_assert_msg(res < 0, "Failed to handle non-null session.d");
2✔
425
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
426
    strerror(errno), errno);
427
  session.d = NULL;
1✔
428

429
  mark_point();
1✔
430
  session.xfer.filename = "foo";
1✔
431
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
432
  ck_assert_msg(res < 0, "Opened active READ data connection unexpectedly");
2✔
433
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
2✔
434
    "Expected EADDRNOTAVAIL (%d) or ECONNREFUSED (%d), got %s (%d)",
435
    EADDRNOTAVAIL, ECONNREFUSED, strerror(errno), errno);
436
  session.xfer.filename = NULL;
1✔
437

438
  /* Open a WRITing data transfer connection...*/
439
  dir = PR_NETIO_IO_WR;
1✔
440

441
  mark_point();
1✔
442
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
443
  ck_assert_msg(res < 0, "Opened active READ data connection unexpectedly");
2✔
444
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
2✔
445
    "Expected EADDRNOTAVAIL (%d) or ECONNREFUSED (%d), got %s (%d)",
446
    EADDRNOTAVAIL, ECONNREFUSED, strerror(errno), errno);
447

448
  mark_point();
1✔
449
  session.xfer.p = NULL;
1✔
450
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
451
  ck_assert_msg(res < 0, "Opened active READ data connection unexpectedly");
2✔
452
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
2✔
453
    "Expected EADDRNOTAVAIL (%d) or ECONNREFUSED (%d), got %s (%d)",
454
    EADDRNOTAVAIL, ECONNREFUSED, strerror(errno), errno);
455

456
  (void) pr_inet_close(p, session.c);
1✔
457
  session.c = NULL;
1✔
458
  if (session.d != NULL) {
1✔
459
    (void) pr_inet_close(p, session.d);
×
460
    session.d = NULL;
×
461
  }
462
}
463
END_TEST
1✔
464

465
START_TEST (data_open_active_rootrevoke_test) {
1✔
466
  int dir = PR_NETIO_IO_RD, local_port, port = INPORT_ANY, sockfd = -1, res;
1✔
467
  conn_t *conn;
468
  config_rec *c;
469
  server_rec *s;
470

471
  conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
1✔
472
  ck_assert_msg(conn != NULL, "Failed to create conn: %s", strerror(errno));
1✔
473

474
  /* Note: these tests REQUIRE that session.c be non-NULL */
475
  session.c = conn;
1✔
476

477
  /* Note: we also need session.c to have valid local/remote_addr, too! */
478
  session.c->local_addr = session.c->remote_addr = pr_netaddr_get_addr(p, "127.0.0.1", NULL);
1✔
479
  ck_assert_msg(session.c->remote_addr != NULL, "Failed to get address: %s",
2✔
480
    strerror(errno));
481

482
  s = pr_parser_server_ctxt_open("127.0.0.1");
1✔
483
  c = add_config_param("RootRevoke", 1, NULL);
1✔
484
  c->argv[0] = palloc(c->pool, sizeof(int));
1✔
485
  *((int *) c->argv[0]) = 1;
1✔
486

487
  tests_stubs_set_main_server(s);
1✔
488

489
  mark_point();
1✔
490
  session.xfer.filename = "foo";
1✔
491
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
492
  ck_assert_msg(res < 0, "Opened active READ data connection unexpectedly");
2✔
493
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
2✔
494
    "Expected EADDRNOTAVAIL (%d) or ECONNREFUSED (%d), got %s (%d)",
495
    EADDRNOTAVAIL, ECONNREFUSED, strerror(errno), errno);
496
  session.xfer.filename = NULL;
1✔
497

498
  mark_point();
1✔
499
  local_port = session.c->local_port;
1✔
500
  session.c->local_port = 21;
1✔
501
  session.xfer.filename = "foo";
1✔
502
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
503
  ck_assert_msg(res < 0, "Opened active READ data connection unexpectedly");
2✔
504
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2✔
505
    strerror(errno), errno);
506
  session.c->local_port = local_port;
1✔
507
  session.xfer.filename = NULL;
1✔
508

509
  mark_point();
1✔
510
  *((int *) c->argv[0]) = 2;
1✔
511
  session.xfer.filename = "foo";
1✔
512
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
513
  ck_assert_msg(res < 0, "Opened active READ data connection unexpectedly");
2✔
514
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
2✔
515
    "Expected EADDRNOTAVAIL (%d) or ECONNREFUSED (%d), got %s (%d)",
516
    EADDRNOTAVAIL, ECONNREFUSED, strerror(errno), errno);
517
  session.xfer.filename = NULL;
1✔
518

519
  mark_point();
1✔
520
  *((int *) c->argv[0]) = 3;
1✔
521
  session.xfer.filename = "foo";
1✔
522
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
523
  ck_assert_msg(res < 0, "Opened active READ data connection unexpectedly");
2✔
524
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
2✔
525
    "Expected EADDRNOTAVAIL (%d) or ECONNREFUSED (%d), got %s (%d)",
526
    EADDRNOTAVAIL, ECONNREFUSED, strerror(errno), errno);
527
  session.xfer.filename = NULL;
1✔
528

529
  (void) pr_config_remove(s->conf, "RootRevoke", 0, FALSE);
1✔
530

531
  (void) pr_inet_close(p, session.c);
1✔
532
  session.c = NULL;
1✔
533
  if (session.d != NULL) {
1✔
534
    (void) pr_inet_close(p, session.d);
×
535
    session.d = NULL;
×
536
  }
537

538
  tests_stubs_set_main_server(NULL);
1✔
539
}
540
END_TEST
1✔
541

542
START_TEST (data_open_passive_test) {
1✔
543
  int dir = PR_NETIO_IO_RD, fd, port = INPORT_ANY, sockfd = -1, res;
1✔
544
  conn_t *data_conn;
545

546
  /* Set the session flags for a passive transfer data connection. */
547
  session.sf_flags |= SF_PASSIVE;
1✔
548

549
  mark_point();
1✔
550
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
551
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
552
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
553
    strerror(errno), errno);
554

555
  /* Note: these tests REQUIRE that session.c be non-NULL, AND that session.d
556
   * be non-NULL.
557
   */
558
  session.c = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
1✔
559
  ck_assert_msg(session.c != NULL, "Failed to create conn: %s",
2✔
560
    strerror(errno));
561

562
  session.d = data_conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
1✔
563
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s",
2✔
564
    strerror(errno));
565

566
  /* Reset the session flags after every failed open. */
567
  session.sf_flags |= SF_PASSIVE;
1✔
568

569
  /* Open a READing data transfer connection...*/
570

571
  mark_point();
1✔
572
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
573
  ck_assert_msg(res < 0, "Failed to handle null arguments");
2✔
574
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
575
    strerror(errno), errno);
576

577
  /* Note: we also need session.c to have valid local/remote_addr, too! */
578
  session.c->local_addr = session.c->remote_addr = pr_netaddr_get_addr(p,
1✔
579
    "127.0.0.1", NULL);
580
  ck_assert_msg(session.c->remote_addr != NULL, "Failed to get address: %s",
2✔
581
    strerror(errno));
582

583
  mark_point();
1✔
584
  data_conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
1✔
585
  fd = data_conn->listen_fd;
1✔
586
  data_conn->listen_fd = dup(0);
1✔
587
  session.d = data_conn;
1✔
588
  session.sf_flags |= SF_PASSIVE;
1✔
589
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
590
  ck_assert_msg(res < 0, "Opened passive READ data connection unexpectedly");
2✔
591
  ck_assert_msg(errno == ENOTSOCK, "Expected ENOTSOCK (%d), got %s (%d)",
2✔
592
    ENOTSOCK, strerror(errno), errno);
593
  (void) close(fd);
1✔
594

595
  /* Open a WRITing data transfer connection...*/
596
  dir = PR_NETIO_IO_WR;
1✔
597

598
  mark_point();
1✔
599
  data_conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
1✔
600
  fd = data_conn->listen_fd;
1✔
601
  data_conn->listen_fd = dup(1);
1✔
602
  session.d = data_conn;
1✔
603
  session.sf_flags |= SF_PASSIVE;
1✔
604
  session.xfer.p = NULL;
1✔
605
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
606
  ck_assert_msg(res < 0, "Opened passive WRITE data connection unexpectedly");
2✔
607
  ck_assert_msg(errno == ENOTSOCK, "Expected ENOTSOCK (%d), got %s (%d)",
2✔
608
    ENOTSOCK, strerror(errno), errno);
609
  (void) close(fd);
1✔
610

611
  mark_point();
1✔
612
  session.sf_flags |= SF_PASSIVE;
1✔
613
  session.xfer.p = NULL;
1✔
614
  res = pr_data_open(NULL, NULL, dir, 0);
1✔
615
  ck_assert_msg(res < 0, "Opened passive WRITE data connection unexpectedly");
2✔
616
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
617
    strerror(errno), errno);
618

619
  (void) pr_inet_close(p, session.c);
1✔
620
  session.c = NULL;
1✔
621
  if (session.d != NULL) {
1✔
622
    (void) pr_inet_close(p, session.d);
×
623
    session.d = NULL;
×
624
  }
625
}
626
END_TEST
1✔
627

628
START_TEST (data_close_test) {
1✔
629
  session.sf_flags |= SF_PASSIVE;
1✔
630
  pr_data_close(TRUE);
1✔
631
  ck_assert_msg(!(session.sf_flags & SF_PASSIVE),
1✔
632
    "Failed to clear SF_PASSIVE session flag");
633

634
  session.sf_flags |= SF_PASSIVE;
1✔
635
  pr_data_close(FALSE);
1✔
636
  ck_assert_msg(!(session.sf_flags & SF_PASSIVE),
2✔
637
    "Failed to clear SF_PASSIVE session flag");
638

639
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
640
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
641

642
  pr_data_close(TRUE);
1✔
643
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
644
}
645
END_TEST
1✔
646

647
START_TEST (data_abort_test) {
1✔
648
  mark_point();
1✔
649
  session.sf_flags |= SF_PASSIVE;
1✔
650
  pr_data_abort(EPERM, TRUE);
1✔
651
  ck_assert_msg(!(session.sf_flags & SF_PASSIVE),
1✔
652
    "Failed to clear SF_PASSIVE session flag");
653

654
  session.sf_flags |= SF_PASSIVE;
1✔
655
  pr_data_abort(EPERM, FALSE);
1✔
656
  ck_assert_msg(!(session.sf_flags & SF_PASSIVE),
2✔
657
    "Failed to clear SF_PASSIVE session flag");
658

659
  mark_point();
1✔
660
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
661
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
662

663
  pr_data_abort(ESPIPE, FALSE);
1✔
664
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
665

666
  mark_point();
1✔
667
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
668
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
669

670
  session.sf_flags = SF_ABORT;
1✔
671
  pr_data_abort(EPIPE, FALSE);
1✔
672
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
673
  session.sf_flags &= ~SF_POST_ABORT;
1✔
674

675
#if defined(ENXIO)
676
  mark_point();
1✔
677
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
678
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
679
  pr_data_abort(ENXIO, FALSE);
1✔
680
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
681
#endif /* ENXIO */
682

683
#if defined(ENOMEM)
684
  mark_point();
1✔
685
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
686
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
687
  pr_data_abort(ENOMEM, FALSE);
1✔
688
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
689
#endif /* ENOMEM */
690

691
#if defined(EBUSY)
692
  mark_point();
1✔
693
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
694
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
695
  pr_data_abort(EBUSY, FALSE);
1✔
696
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
697
#endif /* EBUSY */
698

699
#if defined(ENOSPC)
700
  mark_point();
1✔
701
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
702
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
703
  pr_data_abort(ENOSPC, FALSE);
1✔
704
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
705
#endif /* ENOSPC */
706

707
#if defined(EFBIG)
708
  mark_point();
1✔
709
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
710
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
711
  pr_data_abort(EFBIG, FALSE);
1✔
712
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
713
#endif /* EFBIG */
714

715
#if defined(ECONNRESET)
716
  mark_point();
1✔
717
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
718
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
719
  pr_data_abort(ECONNRESET, FALSE);
1✔
720
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
721
#endif /* ECONNRESET */
722

723
  mark_point();
1✔
724
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
725
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
726
  pr_data_abort(-5432, FALSE);
1✔
727
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
728
}
729
END_TEST
1✔
730

731
START_TEST (data_reset_test) {
1✔
732
  mark_point();
1✔
733

734
  /* Set a session flag, make sure it's cleared properly. */
735
  session.sf_flags |= SF_PASSIVE;
1✔
736
  pr_data_reset();
1✔
737
  ck_assert_msg(session.d == NULL, "Expected NULL session.d, got %p", session.d);
1✔
738
  ck_assert_msg(!(session.sf_flags & SF_PASSIVE),
2✔
739
    "SF_PASSIVE session flag not cleared");
740

741
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
742
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
743

744
  pr_data_reset();
1✔
745
  ck_assert_msg(session.d == NULL, "Expected NULL session.d, got %p", session.d);
2✔
746
  ck_assert_msg(!(session.sf_flags & SF_PASSIVE),
2✔
747
    "SF_PASSIVE session flag not cleared");
748
}
749
END_TEST
1✔
750

751
START_TEST (data_cleanup_test) {
1✔
752
  mark_point();
1✔
753

754
  /* Set a session flag, make sure it's cleared properly. */
755
  session.sf_flags |= SF_PASSIVE;
1✔
756
  pr_data_cleanup();
1✔
757
  ck_assert_msg(session.d == NULL, "Expected NULL session.d, got %p", session.d);
1✔
758
  ck_assert_msg(session.sf_flags & SF_PASSIVE,
2✔
759
    "SF_PASSIVE session flag not preserved");
760
  ck_assert_msg(session.xfer.xfer_type == STOR_DEFAULT, "Expected %d, got %d",
2✔
761
    STOR_DEFAULT, session.xfer.xfer_type);
762

763
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
764
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
765

766
  pr_data_cleanup();
1✔
767
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
2✔
768
}
769
END_TEST
1✔
770

771
START_TEST (data_clear_xfer_pool_test) {
1✔
772
  int xfer_type = 7;
1✔
773

774
  mark_point();
1✔
775
  pr_data_clear_xfer_pool();
1✔
776
  ck_assert_msg(session.xfer.p == NULL, "Failed to clear session.xfer.p");
1✔
777

778
  session.xfer.xfer_type = xfer_type;
1✔
779
  session.xfer.p = make_sub_pool(p);
1✔
780

781
  mark_point();
1✔
782
  pr_data_clear_xfer_pool();
1✔
783
  ck_assert_msg(session.xfer.p == NULL, "Failed to clear session.xfer.p");
2✔
784
  ck_assert_msg(session.xfer.xfer_type == xfer_type, "Expected %d, got %d",
2✔
785
    xfer_type, session.xfer.xfer_type);
786
}
787
END_TEST
1✔
788

789
START_TEST (data_xfer_read_binary_test) {
1✔
790
  int res;
791
  char *buf, *expected;
792
  size_t bufsz, expected_len;
793
  cmd_rec *cmd;
794

795
  pr_data_clear_xfer_pool();
1✔
796
  pr_data_reset();
1✔
797

798
  res = pr_data_xfer(NULL, 0);
1✔
799
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
800
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
801
    strerror(errno), errno);
802

803
  bufsz = 1024;
1✔
804
  buf = palloc(p, bufsz);
1✔
805

806
  res = pr_data_xfer(buf, 0);
1✔
807
  ck_assert_msg(res < 0, "Failed to handle zero buffer length");
2✔
808
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
809
    strerror(errno), errno);
810

811
  mark_point();
1✔
812
  res = pr_data_xfer(buf, bufsz);
1✔
813
  ck_assert_msg(res < 0, "Transferred data unexpectedly");
2✔
814
  ck_assert_msg(errno == ECONNABORTED,
2✔
815
    "Expected ECONNABORTED (%d), got %s (%d)", ECONNABORTED,
816
    strerror(errno), errno);
817

818
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
819
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
820

821
  /* read binary data */
822
  session.xfer.direction = PR_NETIO_IO_RD;
1✔
823

824
  /* Note: this string comes from the data_read_cb() we register with our
825
   * DATA stream callback.
826
   */
827
  expected = "Hello,\r\n World!\r\n";
1✔
828
  expected_len = strlen(expected);
1✔
829

830
  mark_point();
1✔
831
  data_write_eagain = TRUE;
1✔
832
  session.xfer.buf = NULL;
1✔
833
  session.xfer.buflen = 0;
1✔
834

835
  res = pr_data_xfer(buf, bufsz);
1✔
836
  ck_assert_msg(res < 0, "Transferred data unexpectedly");
2✔
837
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
838
    strerror(errno), errno);
839

840
  res = data_open_streams(session.d, PR_NETIO_STRM_DATA);
1✔
841
  ck_assert_msg(res == 0, "Failed to open streams on session.d: %s",
2✔
842
    strerror(errno));
843

844
  mark_point();
1✔
845
  session.xfer.buf = NULL;
1✔
846
  session.xfer.buflen = 0;
1✔
847

848
  res = pr_data_xfer(buf, bufsz);
1✔
849
  ck_assert_msg((size_t) res == expected_len, "Expected %lu, got %d",
2✔
850
    (unsigned long) expected_len, res);
851

852
  session.c = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
853
  ck_assert_msg(session.c != NULL, "Failed to create conn: %s", strerror(errno));
2✔
854

855
  res = data_open_streams(session.c, PR_NETIO_STRM_CTRL);
1✔
856
  ck_assert_msg(res == 0, "Failed to open streams on session.c: %s",
2✔
857
    strerror(errno));
858

859
  mark_point();
1✔
860
  session.xfer.buf = NULL;
1✔
861
  session.xfer.buflen = 0;
1✔
862

863
  res = pr_data_xfer(buf, bufsz);
1✔
864
  ck_assert_msg(res == (int) expected_len, "Expected %lu, got %d",
2✔
865
    (unsigned long) expected_len, res);
866
  ck_assert_msg(session.xfer.buflen == 0,
2✔
867
    "Expected session.xfer.buflen 0, got %lu",
868
    (unsigned long) session.xfer.buflen);
869

870
  mark_point();
1✔
871
  session.xfer.buf = NULL;
1✔
872
  session.xfer.buflen = 0;
1✔
873
  cmd = pr_cmd_alloc(p, 1, pstrdup(p, "syst"));
1✔
874
  tests_stubs_set_next_cmd(cmd);
1✔
875
  data_read_eagain = TRUE;
1✔
876

877
  res = pr_data_xfer(buf, bufsz);
1✔
878
  ck_assert_msg(res == (int) expected_len, "Expected %lu, got %d",
2✔
879
    (unsigned long) expected_len, res);
880
  ck_assert_msg(session.xfer.buflen == 0,
2✔
881
    "Expected session.xfer.buflen 0, got %lu",
882
    (unsigned long) session.xfer.buflen);
883
}
884
END_TEST
1✔
885

886
START_TEST (data_xfer_write_binary_test) {
1✔
887
  int res;
888
  char *buf;
889
  size_t buflen;
890

891
  pr_data_clear_xfer_pool();
1✔
892
  pr_data_reset();
1✔
893

894
  res = pr_data_xfer(NULL, 0);
1✔
895
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
896
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
897
    strerror(errno), errno);
898

899
  buf = "Hello, World!\n";
1✔
900
  buflen = strlen(buf);
1✔
901

902
  res = pr_data_xfer(buf, 0);
1✔
903
  ck_assert_msg(res < 0, "Failed to handle zero buffer length");
2✔
904
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
905
    strerror(errno), errno);
906

907
  mark_point();
1✔
908
  res = pr_data_xfer(buf, buflen);
1✔
909
  ck_assert_msg(res < 0, "Transferred data unexpectedly");
2✔
910
  ck_assert_msg(errno == ECONNABORTED,
2✔
911
    "Expected ECONNABORTED (%d), got %s (%d)", ECONNABORTED,
912
    strerror(errno), errno);
913

914
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
915
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
916

917
  /* write binary data */
918
  session.xfer.direction = PR_NETIO_IO_WR;
1✔
919
  session.xfer.p = make_sub_pool(p);
1✔
920
  session.xfer.buflen = 1024;
1✔
921
  session.xfer.buf = pcalloc(p, session.xfer.buflen);
1✔
922

923
  mark_point();
1✔
924
  data_write_eagain = TRUE;
1✔
925
  res = pr_data_xfer(buf, buflen);
1✔
926
  ck_assert_msg(res < 0, "Transferred data unexpectedly");
2✔
927
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
928
    strerror(errno), errno);
929

930
  res = data_open_streams(session.d, PR_NETIO_STRM_DATA);
1✔
931
  ck_assert_msg(res == 0, "Failed to open streams on session.d: %s",
2✔
932
    strerror(errno));
933

934
  mark_point();
1✔
935
  res = pr_data_xfer(buf, buflen);
1✔
936
  ck_assert_msg(res == (int) buflen, "Expected %lu, got %d",
2✔
937
    (unsigned long) buflen, res);
938

939
  session.c = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
940
  ck_assert_msg(session.c != NULL, "Failed to create conn: %s", strerror(errno));
2✔
941

942
  res = data_open_streams(session.c, PR_NETIO_STRM_CTRL);
1✔
943
  ck_assert_msg(res == 0, "Failed to open streams on session.c: %s",
2✔
944
    strerror(errno));
945

946
  mark_point();
1✔
947
  res = pr_data_xfer(buf, buflen);
1✔
948
  ck_assert_msg(res == (int) buflen, "Expected %lu, got %d",
2✔
949
    (unsigned long) buflen, res);
950

951
  /* Now that we no longer do an egregious memcpy() into session.xfer.buf
952
   * for binary transfers, we cannot use the contents of session.xfer.buf
953
   * for additional assertions.  The integration tests can cover those
954
   * assertions.
955
   */
956
}
957
END_TEST
1✔
958

959
START_TEST (data_xfer_read_ascii_test) {
1✔
960
  int res;
961
  char *buf, *expected;
962
  size_t bufsz, expected_len;
963
  cmd_rec *cmd;
964

965
  pr_data_clear_xfer_pool();
1✔
966
  pr_data_reset();
1✔
967

968
  res = pr_data_xfer(NULL, 0);
1✔
969
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
970
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
971
    strerror(errno), errno);
972

973
  bufsz = 1024;
1✔
974
  buf = palloc(p, bufsz);
1✔
975

976
  res = pr_data_xfer(buf, 0);
1✔
977
  ck_assert_msg(res < 0, "Failed to handle zero buffer length");
2✔
978
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
979
    strerror(errno), errno);
980

981
  mark_point();
1✔
982
  res = pr_data_xfer(buf, bufsz);
1✔
983
  ck_assert_msg(res < 0, "Transferred data unexpectedly");
2✔
984
  ck_assert_msg(errno == ECONNABORTED,
2✔
985
    "Expected ECONNABORTED (%d), got %s (%d)", ECONNABORTED,
986
    strerror(errno), errno);
987

988
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
989
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
990

991
  /* read ASCII data */
992
  session.xfer.direction = PR_NETIO_IO_RD;
1✔
993
  session.xfer.p = make_sub_pool(p);
1✔
994
  session.xfer.bufsize = 1024;
1✔
995

996
  /* Note: this string comes from the data_read_cb() we register with our
997
   * DATA stream callback.
998
   */
999
  expected = "Hello,\n World!\n";
1✔
1000
  expected_len = strlen(expected);
1✔
1001

1002
  mark_point();
1✔
1003
  data_write_eagain = TRUE;
1✔
1004
  pr_ascii_ftp_reset();
1✔
1005
  session.xfer.buf = pcalloc(p, session.xfer.bufsize);
1✔
1006
  session.xfer.buflen = 0;
1✔
1007

1008
  session.sf_flags |= SF_ASCII;
1✔
1009
  res = pr_data_xfer(buf, bufsz);
1✔
1010
  session.sf_flags &= ~SF_ASCII;
1✔
1011

1012
  ck_assert_msg(res < 0, "Transferred data unexpectedly");
2✔
1013
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1014
    strerror(errno), errno);
1015

1016
  res = data_open_streams(session.d, PR_NETIO_STRM_DATA);
1✔
1017
  ck_assert_msg(res == 0, "Failed to open streams on session.d: %s",
2✔
1018
    strerror(errno));
1019

1020
  mark_point();
1✔
1021
  pr_ascii_ftp_reset();
1✔
1022
  session.xfer.buf = pcalloc(p, session.xfer.bufsize);
1✔
1023
  session.xfer.buflen = 0;
1✔
1024

1025
  session.sf_flags |= SF_ASCII;
1✔
1026
  res = pr_data_xfer(buf, bufsz);
1✔
1027
  session.sf_flags &= ~SF_ASCII;
1✔
1028

1029
  ck_assert_msg((size_t) res == expected_len, "Expected %lu, got %d",
2✔
1030
    (unsigned long) expected_len, res);
1031

1032
  session.c = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1033
  ck_assert_msg(session.c != NULL, "Failed to create conn: %s", strerror(errno));
2✔
1034

1035
  res = data_open_streams(session.c, PR_NETIO_STRM_CTRL);
1✔
1036
  ck_assert_msg(res == 0, "Failed to open streams on session.c: %s",
2✔
1037
    strerror(errno));
1038

1039
  mark_point();
1✔
1040
  pr_ascii_ftp_reset();
1✔
1041
  session.xfer.buf = pcalloc(p, session.xfer.bufsize);
1✔
1042
  session.xfer.buflen = 0;
1✔
1043

1044
  session.sf_flags |= SF_ASCII;
1✔
1045
  res = pr_data_xfer(buf, bufsz);
1✔
1046
  session.sf_flags &= ~SF_ASCII;
1✔
1047

1048
  ck_assert_msg(res == (int) expected_len, "Expected %lu, got %d",
2✔
1049
    (unsigned long) expected_len, res);
1050
  ck_assert_msg(session.xfer.buflen == 0,
2✔
1051
    "Expected session.xfer.buflen 0, got %lu",
1052
    (unsigned long) session.xfer.buflen);
1053
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
2✔
1054
    "Expected '%s', got '%.100s'", expected, buf);
1055

1056
  mark_point();
1✔
1057
  cmd = pr_cmd_alloc(p, 1, pstrdup(p, "noop"));
1✔
1058
  tests_stubs_set_next_cmd(cmd);
1✔
1059
  pr_ascii_ftp_reset();
1✔
1060
  session.xfer.buf = pcalloc(p, session.xfer.bufsize);
1✔
1061
  session.xfer.buflen = 0;
1✔
1062

1063
  session.sf_flags |= SF_ASCII;
1✔
1064
  res = pr_data_xfer(buf, bufsz);
1✔
1065
  session.sf_flags &= ~SF_ASCII;
1✔
1066

1067
  ck_assert_msg(res == (int) expected_len, "Expected %lu, got %d",
2✔
1068
    (unsigned long) expected_len, res);
1069
  ck_assert_msg(session.xfer.buflen == 0,
2✔
1070
    "Expected session.xfer.buflen 0, got %lu",
1071
    (unsigned long) session.xfer.buflen);
1072
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
2✔
1073
    "Expected '%s', got '%.100s'", expected, buf);
1074

1075
  mark_point();
1✔
1076
  cmd = pr_cmd_alloc(p, 1, pstrdup(p, "pasv"));
1✔
1077
  tests_stubs_set_next_cmd(cmd);
1✔
1078
  pr_ascii_ftp_reset();
1✔
1079
  session.xfer.buf = pcalloc(p, session.xfer.bufsize);
1✔
1080
  session.xfer.buflen = 0;
1✔
1081

1082
  session.sf_flags |= SF_ASCII;
1✔
1083
  res = pr_data_xfer(buf, bufsz);
1✔
1084
  session.sf_flags &= ~SF_ASCII;
1✔
1085

1086
  ck_assert_msg(res == (int) expected_len, "Expected %lu, got %d",
2✔
1087
    (unsigned long) expected_len, res);
1088
  ck_assert_msg(session.xfer.buflen == 0,
2✔
1089
    "Expected session.xfer.buflen 0, got %lu",
1090
    (unsigned long) session.xfer.buflen);
1091
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
2✔
1092
    "Expected '%s', got '%.100s'", expected, buf);
1093

1094
  /* Bug#4237 happened because of insufficient testing of the edge case
1095
   * where the LAST character in the buffer is a CR.
1096
   *
1097
   * Note that to properly test this, we need to KEEP the same session.xfer.buf
1098
   * in place, and do the read TWICE (at least; maybe more).
1099
   */
1100

1101
  mark_point();
1✔
1102
  pr_ascii_ftp_reset();
1✔
1103
  session.xfer.buf = pcalloc(p, session.xfer.bufsize);
1✔
1104
  session.xfer.buflen = 0;
1✔
1105
  data_read_dangling_cr = TRUE;
1✔
1106

1107
  session.sf_flags |= SF_ASCII;
1✔
1108
  res = pr_data_xfer(buf, bufsz);
1✔
1109
  session.sf_flags &= ~SF_ASCII;
1✔
1110

1111
  ck_assert_msg(res == (int) expected_len, "Expected %lu, got %d",
2✔
1112
    (unsigned long) expected_len, res);
1113
  ck_assert_msg(session.xfer.buflen == 1,
2✔
1114
    "Expected session.xfer.buflen 1, got %lu",
1115
    (unsigned long) session.xfer.buflen);
1116
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
2✔
1117
    "Expected '%s', got '%.100s'", expected, buf);
1118
}
1119
END_TEST
1✔
1120

1121
START_TEST (data_xfer_read_ascii_with_abor_test) {
1✔
1122
  int res;
1123
  char *buf, *expected;
1124
  size_t bufsz, expected_len;
1125
  cmd_rec *cmd;
1126

1127
  pr_data_clear_xfer_pool();
1✔
1128
  pr_data_reset();
1✔
1129

1130
  bufsz = 1024;
1✔
1131
  buf = palloc(p, bufsz);
1✔
1132

1133
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1134
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
1✔
1135

1136
  /* read ASCII data */
1137
  session.xfer.direction = PR_NETIO_IO_RD;
1✔
1138
  session.xfer.p = make_sub_pool(p);
1✔
1139
  session.xfer.bufsize = 1024;
1✔
1140

1141
  /* Note: this string comes from the data_read_cb() we register with our
1142
   * DATA stream callback.
1143
   */
1144
  expected = "Hello,\n World!\n";
1✔
1145
  expected_len = strlen(expected);
1✔
1146

1147
  res = data_open_streams(session.d, PR_NETIO_STRM_DATA);
1✔
1148
  ck_assert_msg(res == 0, "Failed to open streams on session.d: %s",
2✔
1149
    strerror(errno));
1150

1151
  session.c = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1152
  ck_assert_msg(session.c != NULL, "Failed to create conn: %s", strerror(errno));
2✔
1153

1154
  res = data_open_streams(session.c, PR_NETIO_STRM_CTRL);
1✔
1155
  ck_assert_msg(res == 0, "Failed to open streams on session.c: %s",
2✔
1156
    strerror(errno));
1157

1158
  mark_point();
1✔
1159
  pr_ascii_ftp_reset();
1✔
1160
  session.xfer.buf = pcalloc(p, session.xfer.bufsize);
1✔
1161
  session.xfer.buflen = 0;
1✔
1162

1163
  mark_point();
1✔
1164

1165
  cmd = pr_cmd_alloc(p, 1, pstrdup(p, "abor"));
1✔
1166
  tests_stubs_set_next_cmd(cmd);
1✔
1167

1168
  pr_ascii_ftp_reset();
1✔
1169
  session.xfer.buf = pcalloc(p, session.xfer.bufsize);
1✔
1170
  session.xfer.buflen = 0;
1✔
1171

1172
  session.sf_flags |= SF_ASCII;
1✔
1173
  res = pr_data_xfer(buf, bufsz);
1✔
1174
  session.sf_flags &= ~SF_ASCII;
1✔
1175

1176
  ck_assert_msg(res == (int) expected_len, "Expected %lu, got %d",
2✔
1177
    (unsigned long) expected_len, res);
1178
  ck_assert_msg(session.xfer.buflen == 0,
2✔
1179
    "Expected session.xfer.buflen 0, got %lu",
1180
    (unsigned long) session.xfer.buflen);
1181
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
2✔
1182
    "Expected '%s', got '%.100s'", expected, buf);
1183
}
1184
END_TEST
1✔
1185

1186
START_TEST (data_xfer_write_ascii_test) {
1✔
1187
  int res;
1188
  char *buf, *ascii_buf;
1189
  size_t buflen, ascii_buflen;
1190
  cmd_rec *cmd;
1191

1192
  pr_data_clear_xfer_pool();
1✔
1193
  pr_data_reset();
1✔
1194

1195
  res = pr_data_xfer(NULL, 0);
1✔
1196
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
1197
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1198
    strerror(errno), errno);
1199

1200
  buf = "Hello,\n World\n";
1✔
1201
  buflen = strlen(buf);
1✔
1202

1203
  ascii_buf = "Hello,\r\n World\r\n";
1✔
1204
  ascii_buflen = strlen(ascii_buf);
1✔
1205

1206
  res = pr_data_xfer(buf, 0);
1✔
1207
  ck_assert_msg(res < 0, "Failed to handle zero buffer length");
2✔
1208
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1209
    strerror(errno), errno);
1210

1211
  mark_point();
1✔
1212
  res = pr_data_xfer(buf, buflen);
1✔
1213
  ck_assert_msg(res < 0, "Transferred data unexpectedly");
2✔
1214
  ck_assert_msg(errno == ECONNABORTED,
2✔
1215
    "Expected ECONNABORTED (%d), got %s (%d)", ECONNABORTED,
1216
    strerror(errno), errno);
1217

1218
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1219
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
2✔
1220

1221
  /* write ASCII data */
1222
  session.xfer.direction = PR_NETIO_IO_WR;
1✔
1223
  session.xfer.p = make_sub_pool(p);
1✔
1224
  session.xfer.buflen = 1024;
1✔
1225
  session.xfer.buf = pcalloc(p, session.xfer.buflen);
1✔
1226

1227
  mark_point();
1✔
1228
  data_write_eagain = TRUE;
1✔
1229
  pr_ascii_ftp_reset();
1✔
1230
  session.sf_flags |= SF_ASCII_OVERRIDE;
1✔
1231
  res = pr_data_xfer(buf, buflen);
1✔
1232
  session.sf_flags &= ~SF_ASCII_OVERRIDE;
1✔
1233

1234
  ck_assert_msg(res < 0, "Transferred data unexpectedly");
2✔
1235
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1236
    strerror(errno), errno);
1237

1238
  res = data_open_streams(session.d, PR_NETIO_STRM_DATA);
1✔
1239
  ck_assert_msg(res == 0, "Failed to open streams on session.d: %s",
2✔
1240
    strerror(errno));
1241

1242
  mark_point();
1✔
1243
  pr_ascii_ftp_reset();
1✔
1244
  session.sf_flags |= SF_ASCII_OVERRIDE;
1✔
1245
  res = pr_data_xfer(buf, buflen);
1✔
1246
  session.sf_flags &= ~SF_ASCII_OVERRIDE;
1✔
1247

1248
  ck_assert_msg(res == (int) buflen, "Expected %lu, got %d",
2✔
1249
    (unsigned long) buflen, res);
1250

1251
  session.c = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1252
  ck_assert_msg(session.c != NULL, "Failed to create conn: %s", strerror(errno));
2✔
1253

1254
  res = data_open_streams(session.c, PR_NETIO_STRM_CTRL);
1✔
1255
  ck_assert_msg(res == 0, "Failed to open streams on session.c: %s",
2✔
1256
    strerror(errno));
1257

1258
  mark_point();
1✔
1259
  pr_ascii_ftp_reset();
1✔
1260
  session.xfer.buflen = 1024;
1✔
1261
  session.xfer.buf = pcalloc(p, session.xfer.buflen);
1✔
1262

1263
  session.sf_flags |= SF_ASCII_OVERRIDE;
1✔
1264
  res = pr_data_xfer(buf, buflen);
1✔
1265
  session.sf_flags &= ~SF_ASCII_OVERRIDE;
1✔
1266

1267
  ck_assert_msg(res == (int) buflen, "Expected %lu, got %d",
2✔
1268
    (unsigned long) buflen, res);
1269
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
2✔
1270
    "Expected session.xfer.buflen %lu, got %lu", (unsigned long) ascii_buflen,
1271
    (unsigned long) session.xfer.buflen);
1272

1273
  mark_point();
1✔
1274
  cmd = pr_cmd_alloc(p, 1, pstrdup(p, "noop"));
1✔
1275
  tests_stubs_set_next_cmd(cmd);
1✔
1276
  pr_ascii_ftp_reset();
1✔
1277
  session.xfer.buflen = 1024;
1✔
1278
  session.xfer.buf = pcalloc(p, session.xfer.buflen);
1✔
1279

1280
  session.sf_flags |= SF_ASCII_OVERRIDE;
1✔
1281
  res = pr_data_xfer(buf, buflen);
1✔
1282
  session.sf_flags &= ~SF_ASCII_OVERRIDE;
1✔
1283

1284
  ck_assert_msg(res == (int) buflen, "Expected %lu, got %d",
2✔
1285
    (unsigned long) buflen, res);
1286
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
2✔
1287
    "Expected session.xfer.buflen %lu, got %lu", (unsigned long) ascii_buflen,
1288
    (unsigned long) session.xfer.buflen);
1289

1290
  session.xfer.p = make_sub_pool(p);
1✔
1291
  mark_point();
1✔
1292
  cmd = pr_cmd_alloc(p, 1, pstrdup(p, "pasv"));
1✔
1293
  tests_stubs_set_next_cmd(cmd);
1✔
1294
  pr_ascii_ftp_reset();
1✔
1295
  session.xfer.buflen = 1024;
1✔
1296
  session.xfer.buf = pcalloc(p, session.xfer.buflen);
1✔
1297

1298
  session.sf_flags |= SF_ASCII_OVERRIDE;
1✔
1299
  res = pr_data_xfer(buf, buflen);
1✔
1300
  session.sf_flags &= ~SF_ASCII_OVERRIDE;
1✔
1301

1302
  ck_assert_msg(res == (int) buflen, "Expected %lu, got %d",
2✔
1303
    (unsigned long) buflen, res);
1304
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
2✔
1305
    "Expected session.xfer.buflen %lu, got %lu", (unsigned long) ascii_buflen,
1306
    (unsigned long) session.xfer.buflen);
1307

1308
  mark_point();
1✔
1309
  pr_ascii_ftp_reset();
1✔
1310
  session.xfer.buflen = 1024;
1✔
1311
  session.xfer.buf = pcalloc(p, session.xfer.buflen);
1✔
1312

1313
  session.sf_flags |= SF_ASCII;
1✔
1314
  res = pr_data_xfer(buf, buflen);
1✔
1315
  session.sf_flags &= ~SF_ASCII;
1✔
1316

1317
  ck_assert_msg(res == (int) buflen, "Expected %lu, got %d",
2✔
1318
    (unsigned long) buflen, res);
1319
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
2✔
1320
    "Expected session.xfer.buflen %lu, got %lu", (unsigned long) ascii_buflen,
1321
    (unsigned long) session.xfer.buflen);
1322
}
1323
END_TEST
1✔
1324

1325
START_TEST (data_xfer_write_ascii_with_abor_test) {
1✔
1326
  int res;
1327
  char *buf, *ascii_buf;
1328
  size_t buflen, ascii_buflen;
1329
  cmd_rec *cmd;
1330

1331
  pr_data_clear_xfer_pool();
1✔
1332
  pr_data_reset();
1✔
1333

1334
  buf = "Hello,\n World\n";
1✔
1335
  buflen = strlen(buf);
1✔
1336

1337
  ascii_buf = "Hello,\r\n World\r\n";
1✔
1338
  ascii_buflen = strlen(ascii_buf);
1✔
1339

1340
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1341
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
1✔
1342

1343
  /* write ASCII data */
1344
  session.xfer.direction = PR_NETIO_IO_WR;
1✔
1345
  session.xfer.p = make_sub_pool(p);
1✔
1346
  session.xfer.buflen = 1024;
1✔
1347
  session.xfer.buf = pcalloc(p, session.xfer.buflen);
1✔
1348

1349
  res = data_open_streams(session.d, PR_NETIO_STRM_DATA);
1✔
1350
  ck_assert_msg(res == 0, "Failed to open streams on session.d: %s",
2✔
1351
    strerror(errno));
1352

1353
  session.c = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1354
  ck_assert_msg(session.c != NULL, "Failed to create conn: %s", strerror(errno));
2✔
1355

1356
  res = data_open_streams(session.c, PR_NETIO_STRM_CTRL);
1✔
1357
  ck_assert_msg(res == 0, "Failed to open streams on session.c: %s",
2✔
1358
    strerror(errno));
1359

1360
  mark_point();
1✔
1361

1362
  cmd = pr_cmd_alloc(p, 1, pstrdup(p, "abor"));
1✔
1363
  tests_stubs_set_next_cmd(cmd);
1✔
1364

1365
  pr_ascii_ftp_reset();
1✔
1366
  session.xfer.buflen = 1024;
1✔
1367
  session.xfer.buf = pcalloc(p, session.xfer.buflen);
1✔
1368

1369
  session.sf_flags |= SF_ASCII_OVERRIDE;
1✔
1370
  res = pr_data_xfer(buf, buflen);
1✔
1371
  session.sf_flags &= ~SF_ASCII_OVERRIDE;
1✔
1372

1373
  ck_assert_msg(res == (int) buflen, "Expected %lu, got %d",
2✔
1374
    (unsigned long) buflen, res);
1375
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
2✔
1376
    "Expected session.xfer.buflen %lu, got %lu", (unsigned long) ascii_buflen,
1377
    (unsigned long) session.xfer.buflen);
1378
}
1379
END_TEST
1✔
1380

1381
START_TEST (data_xfer_peek_nonsocket_test) {
1✔
1382
  int fd, res, strm_fd;
1383
  char *buf, *expected;
1384
  size_t bufsz, expected_len;
1385

1386
  pr_data_clear_xfer_pool();
1✔
1387
  pr_data_reset();
1✔
1388

1389
  mark_point();
1✔
1390
  bufsz = 1024;
1✔
1391
  buf = palloc(p, bufsz);
1✔
1392
  session.d = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1393
  ck_assert_msg(session.d != NULL, "Failed to create conn: %s", strerror(errno));
1✔
1394

1395
  /* read binary data */
1396
  session.xfer.direction = PR_NETIO_IO_RD;
1✔
1397

1398
  /* Note: this string comes from the data_read_cb() we register with our
1399
   * DATA stream callback.
1400
   */
1401
  expected = "Hello,\r\n World!\r\n";
1✔
1402
  expected_len = strlen(expected);
1✔
1403

1404
  session.xfer.buf = NULL;
1✔
1405
  session.xfer.buflen = 0;
1✔
1406

1407
  res = data_open_streams(session.d, PR_NETIO_STRM_DATA);
1✔
1408
  ck_assert_msg(res == 0, "Failed to open streams on session.d: %s",
2✔
1409
    strerror(errno));
1410

1411
  session.c = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
1✔
1412
  ck_assert_msg(session.c != NULL, "Failed to create conn: %s", strerror(errno));
2✔
1413

1414
  res = data_open_streams(session.c, PR_NETIO_STRM_CTRL);
1✔
1415
  ck_assert_msg(res == 0, "Failed to open streams on session.c: %s",
2✔
1416
    strerror(errno));
1417

1418
  fd = tmpfile_fd();
1✔
1419
  if (fd < 0) {
1✔
1420
    return;
1421
  }
1422

1423
  strm_fd = PR_NETIO_FD(session.c->instrm);
1✔
1424
  PR_NETIO_FD(session.c->instrm) = fd;
1✔
1425

1426
  (void) write(fd, "FOO\r\n", 5);
1✔
1427
  rewind_fd(fd);
1✔
1428

1429
  mark_point();
1✔
1430
  session.xfer.buf = NULL;
1✔
1431
  session.xfer.buflen = 0;
1✔
1432
  data_write_eagain = TRUE;
1✔
1433

1434
  res = pr_data_xfer(buf, bufsz);
1✔
1435
  ck_assert_msg(res == (int) expected_len, "Expected %lu, got %d",
1✔
1436
    (unsigned long) expected_len, res);
1437
  ck_assert_msg(session.xfer.buflen == 0,
2✔
1438
    "Expected session.xfer.buflen 0, got %lu",
1439
    (unsigned long) session.xfer.buflen);
1440

1441
  (void) close(fd);
1✔
1442

1443
  PR_NETIO_FD(session.c->instrm) = strm_fd;
1✔
1444
  (void) pr_inet_close(p, session.c);
1✔
1445
  session.c = NULL;
1✔
1446
  if (session.d != NULL) {
1✔
1447
    (void) pr_inet_close(p, session.d);
1✔
1448
    session.d = NULL;
1✔
1449
  }
1450
}
1451
END_TEST
1452

1453
Suite *tests_get_data_suite(void) {
894✔
1454
  Suite *suite;
1455
  TCase *testcase;
1456

1457
  suite = suite_create("data");
894✔
1458

1459
  testcase = tcase_create("base");
894✔
1460
  tcase_add_checked_fixture(testcase, set_up, tear_down);
894✔
1461

1462
  tcase_add_test(testcase, data_get_timeout_test);
894✔
1463
  tcase_add_test(testcase, data_set_timeout_test);
894✔
1464
  tcase_add_test(testcase, data_ignore_ascii_test);
894✔
1465
  tcase_add_test(testcase, data_sendfile_test);
894✔
1466

1467
  tcase_add_test(testcase, data_init_test);
894✔
1468
  tcase_add_test(testcase, data_open_active_test);
894✔
1469
  tcase_add_test(testcase, data_open_active_rootrevoke_test);
894✔
1470
  tcase_add_test(testcase, data_open_passive_test);
894✔
1471
  tcase_add_test(testcase, data_close_test);
894✔
1472
  tcase_add_test(testcase, data_abort_test);
894✔
1473
  tcase_add_test(testcase, data_reset_test);
894✔
1474
  tcase_add_test(testcase, data_cleanup_test);
894✔
1475
  tcase_add_test(testcase, data_clear_xfer_pool_test);
894✔
1476
  tcase_add_test(testcase, data_xfer_read_binary_test);
894✔
1477
  tcase_add_test(testcase, data_xfer_write_binary_test);
894✔
1478
  tcase_add_test(testcase, data_xfer_read_ascii_test);
894✔
1479
  tcase_add_test(testcase, data_xfer_read_ascii_with_abor_test);
894✔
1480
  tcase_add_test(testcase, data_xfer_write_ascii_test);
894✔
1481
  tcase_add_test(testcase, data_xfer_write_ascii_with_abor_test);
894✔
1482
  tcase_add_test(testcase, data_xfer_peek_nonsocket_test);
894✔
1483

1484
  /* Allow a longer timeout on these tests, as they will need a second or
1485
   * two to actually run through the test itself, plus overhead.
1486
   */
1487
  tcase_set_timeout(testcase, 5);
894✔
1488

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

© 2026 Coveralls, Inc