summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--changes/bug92544
-rw-r--r--changes/bug92674
-rwxr-xr-xcontrib/cov-blame48
-rwxr-xr-xcontrib/coverage35
-rw-r--r--src/common/sandbox.c16
-rw-r--r--src/or/circuitlist.c6
-rw-r--r--src/or/circuitmux.h3
-rw-r--r--src/or/replaycache.c15
-rw-r--r--src/test/test_circuitlist.c6
-rw-r--r--src/test/test_pt.c25
-rw-r--r--src/test/test_replay.c170
12 files changed, 305 insertions, 30 deletions
diff --git a/Makefile.am b/Makefile.am
index 1bc1077ebb..0361d87cec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -71,6 +71,9 @@ test: all
test-network: all
./src/test/test-network.sh
+reset-gcov:
+ rm -f src/*/*.gcda
+
# Avoid strlcpy.c, strlcat.c, aes.c, OpenBSD_malloc_Linux.c, sha256.c,
# eventdns.[hc], tinytest*.[ch]
check-spaces:
diff --git a/changes/bug9254 b/changes/bug9254
new file mode 100644
index 0000000000..5179bdc523
--- /dev/null
+++ b/changes/bug9254
@@ -0,0 +1,4 @@
+ o Minor bugfixes:
+ - Fix a spurious compilation warning with some older versions of
+ GCC on FreeBSD. Fixes bug 9254; bugfix on 0.2.4.14-alpha.
+
diff --git a/changes/bug9267 b/changes/bug9267
new file mode 100644
index 0000000000..95a621148d
--- /dev/null
+++ b/changes/bug9267
@@ -0,0 +1,4 @@
+ o Minor bugfixes:
+ - Added optional parameter to contrib/coverage script to specify directory
+ to put gcov files in, and added reset-gcov target to top-level makefile.
+ Fixes bug #9267.
diff --git a/contrib/cov-blame b/contrib/cov-blame
new file mode 100755
index 0000000000..601f211952
--- /dev/null
+++ b/contrib/cov-blame
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+import os
+import re
+import subprocess
+import sys
+
+def handle_file(source_fname, cov_fname):
+
+ lines_blm = subprocess.Popen(["git", "blame", source_fname], stdout=subprocess.PIPE).stdout.readlines()
+ lines_cov = open(cov_fname).readlines()
+
+ # XXXX expensive!
+ while re.match(r'\s*-:\s*0:', lines_cov[0]):
+ del lines_cov[0]
+
+ if len(lines_blm) != len(lines_cov):
+ print >>sys.stderr, "MISMATCH IN NUMBER OF LINES in",source_fname
+
+ for b,c in zip(lines_blm, lines_cov):
+ m = re.match(r'\s*([^\s:]+):', c)
+ if not m:
+ print >>sys.stderr, "CONFUSING LINE %r"% c
+ cov = 'X'
+ elif m.group(1) == '-':
+ cov = '-'
+ elif m.group(1)[0] == '#':
+ cov = '#'
+ elif m.group(1)[0].isdigit():
+ cov = '1'
+ else:
+ print >>sys.stderr, "CONFUSING LINE %r"% c
+ cov = 'X'
+
+ print cov, b,
+
+COV_DIR = sys.argv[1]
+SOURCES = sys.argv[2:]
+
+for fn in SOURCES:
+ _, base = os.path.split(fn)
+ cfn = os.path.join(COV_DIR, base)
+ cfn += ".gcov"
+ if os.path.exists(cfn):
+ handle_file(fn, cfn)
+ else:
+ print >>sys.stderr, "NO FILE EXISTS CALLED ",cfn
+
diff --git a/contrib/coverage b/contrib/coverage
index f51649a78e..f4ae475828 100755
--- a/contrib/coverage
+++ b/contrib/coverage
@@ -5,9 +5,42 @@
# coverage -- run gcov on the appropriate set of object files to extract
# coverage information.
+dst=$1
+
for fn in src/or/*.c src/common/*.c; do
BN=`basename $fn`
DN=`dirname $fn`
F=`echo $BN | sed -e 's/\.c$//;'`
- gcov -o $DN/src_*$F.o $fn
+ GC="${BN}.gcov"
+ # Figure out the object file names
+ ONS=`echo ${DN}/src_*-${F}.o`
+ ONS_WILDCARD_LITERAL="${DN}/src_*-${F}.o"
+ # If the wildcard didn't expand, no files
+ if [ "$ONS" != "${ONS_WILDCARD_LITERAL}" ]
+ then
+ for on in $ONS; do
+ # We should have a gcno file
+ GCNO=`echo $on | sed -e 's/\.o$/\.gcno/;'`
+ if [ -e $GCNO ]
+ then
+ # No need to test for gcda, since gcov assumes no execution
+ # if it's absent
+ rm -f $GC
+ gcov -o $on $fn
+ if [ -e $GC ]
+ then
+ if [ -n $dst ]
+ then
+ mv $GC $dst/$GC
+ fi
+ else
+ echo "gcov -o $on $fn didn't make a .gcov file"
+ fi
+ else
+ echo "Couldn't find gcno file for $on"
+ fi
+ done
+ else
+ echo "No object file found matching source file $fn"
+ fi
done
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index 68be89e881..dbb1657cdb 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -13,9 +13,10 @@
#include <string.h>
#include <stdlib.h>
+#include "orconfig.h"
#include "sandbox.h"
#include "torlog.h"
-#include "orconfig.h"
+#include "util.h"
#if defined(HAVE_SECCOMP_H) && defined(__linux__)
#define USE_LIBSECCOMP
@@ -202,7 +203,7 @@ static void
sigsys_debugging(int nr, siginfo_t *info, void *void_context)
{
ucontext_t *ctx = (ucontext_t *) (void_context);
- char message[64];
+ char message[256];
int rv = 0, syscall, length, err;
(void) nr;
@@ -214,11 +215,12 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context)
syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
- /* XXXX Avoid use of snprintf; it isn't on the list of Stuff You're Allowed
- * To Do In A Signal Handler. */
- length = snprintf(message, sizeof(message),
- "\n\n(Sandbox) bad syscall (%d) was caught.\n",
- syscall);
+ strlcpy(message, "\n\n(Sandbox) Caught a bad syscall attempt (syscall 0x",
+ sizeof(message));
+ (void) format_hex_number_sigsafe(syscall, message+strlen(message),
+ sizeof(message)-strlen(message));
+ strlcat(message, ")\n", sizeof(message));
+ length = strlen(message);
err = 0;
if (sigsys_debugging_fd >= 0) {
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 70c8980055..5e51301ceb 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1642,8 +1642,10 @@ static size_t
n_cells_in_circ_queues(const circuit_t *c)
{
size_t n = c->n_chan_cells.n;
- if (! CIRCUIT_IS_ORIGIN(c))
- n += TO_OR_CIRCUIT((circuit_t*)c)->p_chan_cells.n;
+ if (! CIRCUIT_IS_ORIGIN(c)) {
+ circuit_t *cc = (circuit_t *) c;
+ n += TO_OR_CIRCUIT(cc)->p_chan_cells.n;
+ }
return n;
}
diff --git a/src/or/circuitmux.h b/src/or/circuitmux.h
index ffa28be06d..ee2f5d1535 100644
--- a/src/or/circuitmux.h
+++ b/src/or/circuitmux.h
@@ -128,7 +128,8 @@ void circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ,
void circuitmux_notify_xmit_destroy(circuitmux_t *cmux);
/* Circuit interface */
-MOCK_DECL(void, circuitmux_attach_circuit, (circuitmux_t *cmux, circuit_t *circ,
+MOCK_DECL(void, circuitmux_attach_circuit, (circuitmux_t *cmux,
+ circuit_t *circ,
cell_direction_t direction));
MOCK_DECL(void, circuitmux_detach_circuit,
(circuitmux_t *cmux, circuit_t *circ));
diff --git a/src/or/replaycache.c b/src/or/replaycache.c
index f136072f61..122efb7030 100644
--- a/src/or/replaycache.c
+++ b/src/or/replaycache.c
@@ -134,7 +134,6 @@ replaycache_scrub_if_needed_internal(time_t present, replaycache_t *r)
const char *digest;
void *valp;
time_t *access_time;
- char scrub_this;
/* sanity check */
if (!r || !(r->digests_seen)) {
@@ -152,20 +151,10 @@ replaycache_scrub_if_needed_internal(time_t present, replaycache_t *r)
/* okay, scrub time */
itr = digestmap_iter_init(r->digests_seen);
while (!digestmap_iter_done(itr)) {
- scrub_this = 0;
digestmap_iter_get(itr, &digest, &valp);
access_time = (time_t *)valp;
- if (access_time) {
- /* aged out yet? */
- if (*access_time < present - r->horizon) scrub_this = 1;
- } else {
- /* Buh? Get rid of it, anyway */
- log_info(LD_BUG, "replaycache_scrub_if_needed_internal() saw a NULL"
- " entry in the digestmap.");
- scrub_this = 1;
- }
-
- if (scrub_this) {
+ /* aged out yet? */
+ if (*access_time < present - r->horizon) {
/* Advance the iterator and remove this one */
itr = digestmap_iter_next_rmv(r->digests_seen, itr);
/* Free the value removed */
diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c
index a233653e16..720b407659 100644
--- a/src/test/test_circuitlist.c
+++ b/src/test/test_circuitlist.c
@@ -62,7 +62,6 @@ circuitmux_detach_mock(circuitmux_t *cmux, circuit_t *circ)
memset(&cdm, 0, sizeof(cdm)); \
} while (0)
-
static void
test_clist_maps(void *arg)
{
@@ -150,8 +149,7 @@ test_clist_maps(void *arg)
tt_assert(! circuit_id_in_use_on_channel(200, ch2));
tt_assert(! circuit_id_in_use_on_channel(100, ch1));
-
-done:
+ done:
tor_free(ch1);
tor_free(ch2);
tor_free(ch3);
@@ -163,8 +161,8 @@ done:
UNMOCK(circuitmux_detach_circuit);
}
-
struct testcase_t circuitlist_tests[] = {
{ "maps", test_clist_maps, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
+
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index 6aa345d568..4970cfff44 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -24,6 +24,8 @@ static void
test_pt_parsing(void)
{
char line[200];
+ transport_t *transport = NULL;
+ tor_addr_t test_addr;
managed_proxy_t *mp = tor_malloc(sizeof(managed_proxy_t));
mp->conf_state = PT_PROTO_INFANT;
@@ -50,7 +52,17 @@ test_pt_parsing(void)
/* correct line */
strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
test_assert(parse_cmethod_line(line, mp) == 0);
- test_assert(smartlist_len(mp->transports));
+ test_assert(smartlist_len(mp->transports) == 1);
+ transport = smartlist_get(mp->transports, 0);
+ /* test registered address of transport */
+ tor_addr_parse(&test_addr, "127.0.0.1");
+ test_assert(tor_addr_eq(&test_addr, &transport->addr));
+ /* test registered port of transport */
+ test_assert(transport->port == 1999);
+ /* test registered SOCKS version of transport */
+ test_assert(transport->socks_version == PROXY_SOCKS5);
+ /* test registered name of transport */
+ test_streq(transport->name, "trebuchet");
reset_mp(mp);
@@ -67,8 +79,17 @@ test_pt_parsing(void)
reset_mp(mp);
/* cowwect */
- strlcpy(line,"SMETHOD trebuchy 127.0.0.1:1999",sizeof(line));
+ strlcpy(line,"SMETHOD trebuchy 127.0.0.2:2999",sizeof(line));
test_assert(parse_smethod_line(line, mp) == 0);
+ test_assert(smartlist_len(mp->transports) == 1);
+ transport = smartlist_get(mp->transports, 0);
+ /* test registered address of transport */
+ tor_addr_parse(&test_addr, "127.0.0.2");
+ test_assert(tor_addr_eq(&test_addr, &transport->addr));
+ /* test registered port of transport */
+ test_assert(transport->port == 2999);
+ /* test registered name of transport */
+ test_streq(transport->name, "trebuchy");
reset_mp(mp);
diff --git a/src/test/test_replay.c b/src/test/test_replay.c
index de841ad594..200bf4dd3e 100644
--- a/src/test/test_replay.c
+++ b/src/test/test_replay.c
@@ -32,6 +32,40 @@ test_replaycache_alloc(void)
}
static void
+test_replaycache_badalloc(void)
+{
+ replaycache_t *r = NULL;
+
+ /* Negative horizon should fail */
+ r = replaycache_new(-600, 300);
+ test_assert(r == NULL);
+ /* Negative interval should get adjusted to zero */
+ r = replaycache_new(600, -300);
+ test_assert(r != NULL);
+ test_eq(r->scrub_interval, 0);
+ replaycache_free(r);
+ /* Negative horizon and negative interval should still fail */
+ r = replaycache_new(-600, -300);
+ test_assert(r == NULL);
+
+ done:
+ if (r) replaycache_free(r);
+
+ return;
+}
+
+static void
+test_replaycache_free_null(void)
+{
+ replaycache_free(NULL);
+ /* Assert that we're here without horrible death */
+ test_assert(1);
+
+ done:
+ return;
+}
+
+static void
test_replaycache_miss(void)
{
replaycache_t *r = NULL;
@@ -45,6 +79,12 @@ test_replaycache_miss(void)
(int)strlen(test_buffer), NULL);
test_eq(result, 0);
+ /* poke the bad-parameter error case too */
+ result =
+ replaycache_add_and_test_internal(1200, NULL, test_buffer,
+ (int)strlen(test_buffer), NULL);
+ test_eq(result, 0);
+
done:
if (r) replaycache_free(r);
@@ -163,16 +203,146 @@ test_replaycache_noexpire(void)
return;
}
+static void
+test_replaycache_scrub(void)
+{
+ replaycache_t *r = NULL;
+ int result;
+
+ r = replaycache_new(600, 300);
+ test_assert(r != NULL);
+
+ /* Set up like in test_replaycache_hit() */
+ result =
+ replaycache_add_and_test_internal(100, r, test_buffer,
+ (int)strlen(test_buffer), NULL);
+ test_eq(result, 0);
+
+ result =
+ replaycache_add_and_test_internal(200, r, test_buffer,
+ (int)strlen(test_buffer), NULL);
+ test_eq(result, 1);
+
+ /*
+ * Poke a few replaycache_scrub_if_needed_internal() error cases that
+ * can't happen through replaycache_add_and_test_internal()
+ */
+
+ /* Null cache */
+ replaycache_scrub_if_needed_internal(300, NULL);
+ /* Assert we're still here */
+ test_assert(1);
+
+ /* Make sure we hit the aging-out case too */
+ replaycache_scrub_if_needed_internal(1500, r);
+ /* Assert that we aged it */
+ test_eq(digestmap_size(r->digests_seen), 0);
+
+ done:
+ if (r) replaycache_free(r);
+
+ return;
+}
+
+static void
+test_replaycache_future(void)
+{
+ replaycache_t *r = NULL;
+ int result;
+ time_t elapsed = 0;
+
+ r = replaycache_new(600, 300);
+ test_assert(r != NULL);
+
+ /* Set up like in test_replaycache_hit() */
+ result =
+ replaycache_add_and_test_internal(100, r, test_buffer,
+ (int)strlen(test_buffer), &elapsed);
+ test_eq(result, 0);
+ /* elapsed should still be 0, since it wasn't written */
+ test_eq(elapsed, 0);
+
+ result =
+ replaycache_add_and_test_internal(200, r, test_buffer,
+ (int)strlen(test_buffer), &elapsed);
+ test_eq(result, 1);
+ /* elapsed should be the time since the last hit */
+ test_eq(elapsed, 100);
+
+ /*
+ * Now let's turn the clock back to get coverage on the cache entry from the
+ * future not-supposed-to-happen case.
+ */
+ result =
+ replaycache_add_and_test_internal(150, r, test_buffer,
+ (int)strlen(test_buffer), &elapsed);
+ /* We should still get a hit */
+ test_eq(result, 1);
+ /* ...but it shouldn't let us see a negative elapsed time */
+ test_eq(elapsed, 0);
+
+ done:
+ if (r) replaycache_free(r);
+
+ return;
+}
+
+static void
+test_replaycache_realtime(void)
+{
+ replaycache_t *r = NULL;
+ /*
+ * Negative so we fail if replaycache_add_test_and_elapsed() doesn't
+ * write to elapsed.
+ */
+ time_t elapsed = -1;
+ int result;
+
+ /* Test the realtime as well as *_internal() entry points */
+ r = replaycache_new(600, 300);
+ test_assert(r != NULL);
+
+ /* This should miss */
+ result =
+ replaycache_add_and_test(r, test_buffer, (int)strlen(test_buffer));
+ test_eq(result, 0);
+
+ /* This should hit */
+ result =
+ replaycache_add_and_test(r, test_buffer, (int)strlen(test_buffer));
+ test_eq(result, 1);
+
+ /* This should hit and return a small elapsed time */
+ result =
+ replaycache_add_test_and_elapsed(r, test_buffer,
+ (int)strlen(test_buffer), &elapsed);
+ test_eq(result, 1);
+ test_assert(elapsed >= 0);
+ test_assert(elapsed <= 5);
+
+ /* Scrub it to exercise that entry point too */
+ replaycache_scrub_if_needed(r);
+
+ done:
+ if (r) replaycache_free(r);
+ return;
+}
+
#define REPLAYCACHE_LEGACY(name) \
{ #name, legacy_test_helper, 0, &legacy_setup, test_replaycache_ ## name }
struct testcase_t replaycache_tests[] = {
REPLAYCACHE_LEGACY(alloc),
+ REPLAYCACHE_LEGACY(badalloc),
+ REPLAYCACHE_LEGACY(free_null),
REPLAYCACHE_LEGACY(miss),
REPLAYCACHE_LEGACY(hit),
REPLAYCACHE_LEGACY(age),
REPLAYCACHE_LEGACY(elapsed),
REPLAYCACHE_LEGACY(noexpire),
+ REPLAYCACHE_LEGACY(scrub),
+ REPLAYCACHE_LEGACY(future),
+ REPLAYCACHE_LEGACY(realtime),
END_OF_TESTCASES
};