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

proftpd / proftpd / 14136377169

28 Mar 2025 07:21PM UTC coverage: 92.663% (-0.4%) from 93.027%
14136377169

push

github

Castaglia
To aid in debugging of unexpectedly malfunctioning authorized SSH keys, add trace logging of any lines of text which are not formatted as expected.

47143 of 50876 relevant lines covered (92.66%)

237.38 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-2023 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, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18
 *
19
 * As a special exemption, The ProFTPD Project team and other respective
20
 * copyright holders give permission to link this program with OpenSSL, and
21
 * distribute the resulting executable, without including the source code for
22
 * OpenSSL in the source distribution.
23
 */
24

25
/* Data API tests */
26

27
#include "tests.h"
28

29
static pool *p = NULL;
30

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

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

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

43
  pr_parser_prepare(p, NULL);
20✔
44

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

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

53
  session.sf_flags = 0;
20✔
54

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

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

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

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

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

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

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

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

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

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

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

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

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

110
  return 0;
111
}
112

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

237
  return buflen;
16✔
238
}
239

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

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

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

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

261
  conn->outstrm = nstrm;
15✔
262

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

488
  tests_stubs_set_main_server(s);
1✔
489

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1164
  mark_point();
1✔
1165

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1361
  mark_point();
1✔
1362

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1454
Suite *tests_get_data_suite(void) {
889✔
1455
  Suite *suite;
1456
  TCase *testcase;
1457

1458
  suite = suite_create("data");
889✔
1459

1460
  testcase = tcase_create("base");
889✔
1461
  tcase_add_checked_fixture(testcase, set_up, tear_down);
889✔
1462

1463
  tcase_add_test(testcase, data_get_timeout_test);
889✔
1464
  tcase_add_test(testcase, data_set_timeout_test);
889✔
1465
  tcase_add_test(testcase, data_ignore_ascii_test);
889✔
1466
  tcase_add_test(testcase, data_sendfile_test);
889✔
1467

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

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

1490
  suite_add_tcase(suite, testcase);
889✔
1491
  return suite;
889✔
1492
}
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