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

proftpd / proftpd / 14579502303

21 Apr 2025 07:06PM UTC coverage: 93.03% (+0.4%) from 92.667%
14579502303

push

github

51358 of 55206 relevant lines covered (93.03%)

219.17 hits per line

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

97.65
/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 &&
20✔
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;
1✔
94

95
  fd = open(data_test_path, O_CREAT|O_RDWR, 0600);
1✔
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) {
1✔
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;
1✔
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,
1✔
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",
1✔
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",
1✔
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",
1✔
131
    PR_TUNABLE_TIMEOUTSTALLED, res);
132
}
1✔
133
END_TEST
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);
1✔
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);
1✔
149

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

155
START_TEST (data_ignore_ascii_test) {
1✔
156
  int res;
1✔
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,
1✔
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);
1✔
165

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

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

172
  res = pr_data_ignore_ascii(FALSE);
1✔
173
  ck_assert_msg(res == FALSE, "Expected FALSE (%d), got %d", FALSE, res);
1✔
174
}
1✔
175
END_TEST
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;
11✔
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;
15✔
243
  pr_netio_stream_t *nstrm;
15✔
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;
15✔
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;
1✔
276
  const char *text;
1✔
277

278
  res = (int) pr_data_sendfile(fd, NULL, 0);
1✔
279
  if (res < 0 &&
1✔
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,
1✔
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");
1✔
291
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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");
1✔
297
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
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");
1✔
303
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
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));
1✔
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));
1✔
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");
1✔
316
  ck_assert_msg(errno == EBADF || errno == EINVAL,
1✔
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,
1✔
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,
1✔
327
    strerror(errno));
328
  res = pr_fsio_close(fh);
1✔
329
  ck_assert_msg(res == 0, "Failed to close '%s': %s", data_test_path,
1✔
330
    strerror(errno));
331

332
  fd = open(data_test_path, O_RDONLY);
1✔
333
  ck_assert_msg(fd >= 0, "Failed to open '%s': %s", data_test_path,
1✔
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");
1✔
363
  ck_assert_msg(session.xfer.filename == NULL, "Expected null filename, got %s",
1✔
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,
1✔
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");
1✔
374
  ck_assert_msg(session.xfer.filename != NULL, "Missing transfer filename");
1✔
375
  ck_assert_msg(strcmp(session.xfer.filename, filename) == 0,
1✔
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,
1✔
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");
1✔
383
  ck_assert_msg(session.xfer.filename != NULL, "Missing transfer filename");
1✔
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,
1✔
389
    "Expected '%s', got '%s'", filename, session.xfer.filename);
390
}
1✔
391
END_TEST
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;
1✔
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,
1✔
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));
1✔
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");
1✔
414
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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",
1✔
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");
1✔
426
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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");
1✔
434
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
1✔
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");
1✔
445
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
1✔
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");
1✔
453
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
1✔
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
}
1✔
464
END_TEST
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;
1✔
469
  config_rec *c;
1✔
470
  server_rec *s;
1✔
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",
1✔
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");
1✔
494
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
1✔
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");
1✔
505
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
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");
1✔
515
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
1✔
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");
1✔
525
  ck_assert_msg(errno == EADDRNOTAVAIL || errno == ECONNREFUSED,
1✔
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
}
1✔
541
END_TEST
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;
1✔
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,
1✔
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",
1✔
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",
1✔
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");
1✔
575
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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",
1✔
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");
1✔
592
  ck_assert_msg(errno == ENOTSOCK, "Expected ENOTSOCK (%d), got %s (%d)",
1✔
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");
1✔
608
  ck_assert_msg(errno == ENOTSOCK, "Expected ENOTSOCK (%d), got %s (%d)",
1✔
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");
1✔
617
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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
}
1✔
627
END_TEST
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),
1✔
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));
1✔
642

643
  pr_data_close(TRUE);
1✔
644
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
645
}
1✔
646
END_TEST
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),
1✔
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));
1✔
663

664
  pr_data_abort(ESPIPE, FALSE);
1✔
665
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
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));
1✔
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");
1✔
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));
1✔
680
  pr_data_abort(ENXIO, FALSE);
1✔
681
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
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));
1✔
688
  pr_data_abort(ENOMEM, FALSE);
1✔
689
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
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));
1✔
696
  pr_data_abort(EBUSY, FALSE);
1✔
697
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
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));
1✔
704
  pr_data_abort(ENOSPC, FALSE);
1✔
705
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
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));
1✔
712
  pr_data_abort(EFBIG, FALSE);
1✔
713
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
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));
1✔
720
  pr_data_abort(ECONNRESET, FALSE);
1✔
721
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
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));
1✔
727
  pr_data_abort(-5432, FALSE);
1✔
728
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
729
}
1✔
730
END_TEST
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),
1✔
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));
1✔
744

745
  pr_data_reset();
1✔
746
  ck_assert_msg(session.d == NULL, "Expected NULL session.d, got %p", session.d);
1✔
747
  ck_assert_msg(!(session.sf_flags & SF_PASSIVE),
1✔
748
    "SF_PASSIVE session flag not cleared");
749
}
1✔
750
END_TEST
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,
1✔
760
    "SF_PASSIVE session flag not preserved");
761
  ck_assert_msg(session.xfer.xfer_type == STOR_DEFAULT, "Expected %d, got %d",
1✔
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));
1✔
766

767
  pr_data_cleanup();
1✔
768
  ck_assert_msg(session.d == NULL, "Failed to close session.d");
1✔
769
}
1✔
770
END_TEST
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");
1✔
785
  ck_assert_msg(session.xfer.xfer_type == xfer_type, "Expected %d, got %d",
1✔
786
    xfer_type, session.xfer.xfer_type);
787
}
1✔
788
END_TEST
789

790
START_TEST (data_xfer_read_binary_test) {
1✔
791
  int res;
1✔
792
  char *buf, *expected;
1✔
793
  size_t bufsz, expected_len;
1✔
794
  cmd_rec *cmd;
1✔
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,
1✔
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");
1✔
809
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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");
1✔
815
  ck_assert_msg(errno == ECONNABORTED,
1✔
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));
1✔
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");
1✔
838
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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",
1✔
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",
1✔
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));
1✔
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",
1✔
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",
1✔
866
    (unsigned long) expected_len, res);
867
  ck_assert_msg(session.xfer.buflen == 0,
1✔
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",
1✔
880
    (unsigned long) expected_len, res);
881
  ck_assert_msg(session.xfer.buflen == 0,
1✔
882
    "Expected session.xfer.buflen 0, got %lu",
883
    (unsigned long) session.xfer.buflen);
884
}
1✔
885
END_TEST
886

887
START_TEST (data_xfer_write_binary_test) {
1✔
888
  int res;
1✔
889
  char *buf;
1✔
890
  size_t buflen;
1✔
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,
1✔
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");
1✔
905
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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");
1✔
911
  ck_assert_msg(errno == ECONNABORTED,
1✔
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));
1✔
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");
1✔
928
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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",
1✔
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",
1✔
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));
1✔
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",
1✔
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",
1✔
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
}
1✔
958
END_TEST
959

960
START_TEST (data_xfer_read_ascii_test) {
1✔
961
  int res;
1✔
962
  char *buf, *expected;
1✔
963
  size_t bufsz, expected_len;
1✔
964
  cmd_rec *cmd;
1✔
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,
1✔
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");
1✔
979
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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");
1✔
985
  ck_assert_msg(errno == ECONNABORTED,
1✔
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));
1✔
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");
1✔
1014
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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",
1✔
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",
1✔
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));
1✔
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",
1✔
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",
1✔
1050
    (unsigned long) expected_len, res);
1051
  ck_assert_msg(session.xfer.buflen == 0,
1✔
1052
    "Expected session.xfer.buflen 0, got %lu",
1053
    (unsigned long) session.xfer.buflen);
1054
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
1✔
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",
1✔
1069
    (unsigned long) expected_len, res);
1070
  ck_assert_msg(session.xfer.buflen == 0,
1✔
1071
    "Expected session.xfer.buflen 0, got %lu",
1072
    (unsigned long) session.xfer.buflen);
1073
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
1✔
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",
1✔
1088
    (unsigned long) expected_len, res);
1089
  ck_assert_msg(session.xfer.buflen == 0,
1✔
1090
    "Expected session.xfer.buflen 0, got %lu",
1091
    (unsigned long) session.xfer.buflen);
1092
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
1✔
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",
1✔
1113
    (unsigned long) expected_len, res);
1114
  ck_assert_msg(session.xfer.buflen == 1,
1✔
1115
    "Expected session.xfer.buflen 1, got %lu",
1116
    (unsigned long) session.xfer.buflen);
1117
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
1✔
1118
    "Expected '%s', got '%.100s'", expected, buf);
1119
}
1✔
1120
END_TEST
1121

1122
START_TEST (data_xfer_read_ascii_with_abor_test) {
1✔
1123
  int res;
1✔
1124
  char *buf, *expected;
1✔
1125
  size_t bufsz, expected_len;
1✔
1126
  cmd_rec *cmd;
1✔
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",
1✔
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));
1✔
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",
1✔
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",
1✔
1178
    (unsigned long) expected_len, res);
1179
  ck_assert_msg(session.xfer.buflen == 0,
1✔
1180
    "Expected session.xfer.buflen 0, got %lu",
1181
    (unsigned long) session.xfer.buflen);
1182
  ck_assert_msg(memcmp(buf, expected, expected_len) == 0,
1✔
1183
    "Expected '%s', got '%.100s'", expected, buf);
1184
}
1✔
1185
END_TEST
1186

1187
START_TEST (data_xfer_write_ascii_test) {
1✔
1188
  int res;
1✔
1189
  char *buf, *ascii_buf;
1✔
1190
  size_t buflen, ascii_buflen;
1✔
1191
  cmd_rec *cmd;
1✔
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,
1✔
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");
1✔
1209
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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");
1✔
1215
  ck_assert_msg(errno == ECONNABORTED,
1✔
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));
1✔
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");
1✔
1236
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
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",
1✔
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",
1✔
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));
1✔
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",
1✔
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",
1✔
1269
    (unsigned long) buflen, res);
1270
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
1✔
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",
1✔
1286
    (unsigned long) buflen, res);
1287
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
1✔
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",
1✔
1304
    (unsigned long) buflen, res);
1305
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
1✔
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",
1✔
1319
    (unsigned long) buflen, res);
1320
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
1✔
1321
    "Expected session.xfer.buflen %lu, got %lu", (unsigned long) ascii_buflen,
1322
    (unsigned long) session.xfer.buflen);
1323
}
1✔
1324
END_TEST
1325

1326
START_TEST (data_xfer_write_ascii_with_abor_test) {
1✔
1327
  int res;
1✔
1328
  char *buf, *ascii_buf;
1✔
1329
  size_t buflen, ascii_buflen;
1✔
1330
  cmd_rec *cmd;
1✔
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",
1✔
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));
1✔
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",
1✔
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",
1✔
1375
    (unsigned long) buflen, res);
1376
  ck_assert_msg(session.xfer.buflen == ascii_buflen,
1✔
1377
    "Expected session.xfer.buflen %lu, got %lu", (unsigned long) ascii_buflen,
1378
    (unsigned long) session.xfer.buflen);
1379
}
1✔
1380
END_TEST
1381

1382
START_TEST (data_xfer_peek_nonsocket_test) {
1✔
1383
  int fd, res, strm_fd;
1✔
1384
  char *buf, *expected;
1✔
1385
  size_t bufsz, expected_len;
1✔
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",
1✔
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));
1✔
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",
1✔
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,
1✔
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) {
890✔
1455
  Suite *suite;
890✔
1456
  TCase *testcase;
890✔
1457

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

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

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

1468
  tcase_add_test(testcase, data_init_test);
890✔
1469
  tcase_add_test(testcase, data_open_active_test);
890✔
1470
  tcase_add_test(testcase, data_open_active_rootrevoke_test);
890✔
1471
  tcase_add_test(testcase, data_open_passive_test);
890✔
1472
  tcase_add_test(testcase, data_close_test);
890✔
1473
  tcase_add_test(testcase, data_abort_test);
890✔
1474
  tcase_add_test(testcase, data_reset_test);
890✔
1475
  tcase_add_test(testcase, data_cleanup_test);
890✔
1476
  tcase_add_test(testcase, data_clear_xfer_pool_test);
890✔
1477
  tcase_add_test(testcase, data_xfer_read_binary_test);
890✔
1478
  tcase_add_test(testcase, data_xfer_write_binary_test);
890✔
1479
  tcase_add_test(testcase, data_xfer_read_ascii_test);
890✔
1480
  tcase_add_test(testcase, data_xfer_read_ascii_with_abor_test);
890✔
1481
  tcase_add_test(testcase, data_xfer_write_ascii_test);
890✔
1482
  tcase_add_test(testcase, data_xfer_write_ascii_with_abor_test);
890✔
1483
  tcase_add_test(testcase, data_xfer_peek_nonsocket_test);
890✔
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);
890✔
1489

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