[master] 5fb1da6 Make all VSL records NUL-terminated
Martin Blix Grydeland
martin at varnish-cache.org
Tue Oct 1 14:48:17 CEST 2013
commit 5fb1da6b569e75b232f2e1b555014231a4d7d064
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Thu Sep 19 14:38:48 2013 +0200
Make all VSL records NUL-terminated
Make all VSL records NUL-terminated so that it is safe to use string
functions on the SHMLOG directly.
diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c
index 0093c74..4aa08ce 100644
--- a/bin/varnishd/cache/cache_shmlog.c
+++ b/bin/varnishd/cache/cache_shmlog.c
@@ -218,13 +218,14 @@ VSL(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, ...)
if (strchr(fmt, '%') == NULL) {
- vslr(tag, vxid, fmt, strlen(fmt));
+ vslr(tag, vxid, fmt, strlen(fmt) + 1);
} else {
va_start(ap, fmt);
n = vsnprintf(buf, mlen, fmt, ap);
va_end(ap);
- if (n > mlen)
- n = mlen;
+ if (n > mlen - 1)
+ n = mlen - 1;
+ buf[n++] = '\0'; /* NUL-terminated */
vslr(tag, vxid, buf, n);
}
}
@@ -261,6 +262,7 @@ void
VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t)
{
unsigned l, mlen;
+ char *p;
Tcheck(t);
if (vsl_tag_is_masked(tag))
@@ -269,16 +271,18 @@ VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t)
/* Truncate */
l = Tlen(t);
- if (l > mlen)
- l = mlen;
+ if (l > mlen - 1)
+ l = mlen - 1;
assert(vsl->wlp < vsl->wle);
/* Flush if necessary */
- if (VSL_END(vsl->wlp, l) >= vsl->wle)
+ if (VSL_END(vsl->wlp, l + 1) >= vsl->wle)
VSL_Flush(vsl, 1);
- assert(VSL_END(vsl->wlp, l) < vsl->wle);
- memcpy(VSL_DATA(vsl->wlp), t.b, l);
+ assert(VSL_END(vsl->wlp, l + 1) < vsl->wle);
+ p = VSL_DATA(vsl->wlp);
+ memcpy(p, t.b, l);
+ p[l++] = '\0'; /* NUL-terminated */
vsl->wlp = vsl_hdr(tag, vsl->wlp, l, vsl->wid);
assert(vsl->wlp < vsl->wle);
vsl->wlr++;
@@ -321,15 +325,16 @@ VSLb(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...)
mlen = cache_param->shm_reclen;
/* Flush if we cannot fit a full size record */
- if (VSL_END(vsl->wlp, mlen) >= vsl->wle)
+ if (VSL_END(vsl->wlp, mlen + 1) >= vsl->wle)
VSL_Flush(vsl, 1);
p = VSL_DATA(vsl->wlp);
va_start(ap, fmt);
n = vsnprintf(p, mlen, fmt, ap);
va_end(ap);
- if (n > mlen)
- n = mlen; /* we truncate long fields */
+ if (n > mlen - 1)
+ n = mlen - 1; /* we truncate long fields */
+ p[n++] = '\0'; /* NUL-terminated */
vsl->wlp = vsl_hdr(tag, vsl->wlp, n, vsl->wid);
assert(vsl->wlp < vsl->wle);
vsl->wlr++;
diff --git a/include/vapi/vsl_int.h b/include/vapi/vsl_int.h
index 2d484f6..196bf98 100644
--- a/include/vapi/vsl_int.h
+++ b/include/vapi/vsl_int.h
@@ -60,7 +60,10 @@
* Each logrecord consist of:
* [n] = ((type & 0xff) << 24) | (length & 0xffff)
* [n + 1] = ((marker & 0x03) << 30) | (identifier & 0x3fffffff)
- * [n + 2] ... [m] = content
+ * [n + 2] ... [m] = content (NUL-terminated)
+ *
+ * Logrecords are NUL-terminated so that string functions can be run
+ * directly on the shmlog data.
*
* Notice that the constants in these macros cannot be changed without
* changing corresponding magic numbers in varnishd/cache/cache_shmlog.c
More information about the varnish-commit
mailing list