Commit 8826e917 authored by Geoff Simmons's avatar Geoff Simmons

Add some checks, and clarify what happens when blob->priv is NULL.

parent 6c38e89d
Pipeline #221 skipped
......@@ -65,6 +65,10 @@ same
Returns true if and only if the two BLOB arguments are the same
object, i.e. they specify exactly the same region of memory.
If the BLOBs are both empty (length is 0 and/or the internal pointer
is NULL), then ``same()`` returns ``true``. If any non-empty BLOB
is compared to an empty BLOB, then ``same()`` returns ``false``.
.. _func_equal:
equal
......@@ -77,6 +81,10 @@ equal
Returns true if and only if the two BLOB arguments have equal contents
(possibly in different memory regions).
As with ``same()``: If the BLOBs are both empty, then ``equal()``
returns ``true``. If any non-empty BLOB is compared to an empty BLOB,
then ``equal()`` returns ``false``.
.. _func_length:
length
......@@ -110,10 +118,10 @@ The value of the returned integer results from the bytes from the BLOB
in ascending order of addresses interpreted according to the
endianness of the system on which Varnish is running.
If the length of the BLOB is 0, then ``integer()`` returns 0 and emits
an error message to the Varnish log using the ``VCL_Error`` tag. If
this happens when ``integer()`` is called in ``vcl_init``, then the
VCL load fails with the error message. If it happens in any other VCL
If the BLOB is empty, then ``integer()`` returns 0 and emits an error
message to the Varnish log using the ``VCL_Error`` tag. If this
happens when ``integer()`` is called in ``vcl_init``, then the VCL
load fails with the error message. If it happens in any other VCL
subroutine, then VCL processing continues. Since 0 can be a legitimate
return value, you should monitor the Varnish log for the error.
......
......@@ -271,12 +271,12 @@ client c1 {
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod blob error: blob length is 0 in blob.integer..$"
expect * = VCL_Error "^vmod blob error: blob is empty in blob.integer..$"
expect * = End
} -run
# VCL load fails if integer() is called for an empty blob in vcl_init
varnish v1 -errvcl {vmod blob error: blob length is 0 in blob.integer()} {
varnish v1 -errvcl {vmod blob error: blob is empty in blob.integer()} {
import blob from "${vmod_topbuild}/src/.libs/libvmod_blob.so";
import blobcode;
backend b { .host = "${bad_ip}"; }
......
......@@ -68,22 +68,30 @@ errmsg(VRT_CTX, const char *fmt, ...)
VCL_BOOL
vmod_same(VRT_CTX __attribute__((unused)), VCL_BLOB b1, VCL_BLOB b2)
{
AN(b1);
AN(b2);
return b1->len == b2->len && b1->priv == b2->priv;
}
VCL_BOOL
vmod_equal(VRT_CTX __attribute__((unused)), VCL_BLOB b1, VCL_BLOB b2)
{
AN(b1);
AN(b2);
if (b1->len != b2->len)
return 0;
if (b1->priv == b2->priv)
return 1;
if (b1->priv == NULL || b2->priv == NULL)
return 0;
return (memcmp(b1->priv, b2->priv, b1->len) == 0);
}
VCL_INT
vmod_length(VRT_CTX __attribute__((unused)), VCL_BLOB b)
{
AN(b);
return b->len;
}
......@@ -92,13 +100,17 @@ vmod_integer(VRT_CTX, VCL_BLOB b, VCL_ENUM padding)
{
VCL_INT i = 0;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(b);
assert(b->len >= 0);
if ((unsigned)b->len >= sizeof(VCL_INT))
return *((VCL_INT *) b->priv);
if (b->len == 0) {
ERR(ctx, "blob length is 0 in blob.integer()");
if (b->len == 0 || b->priv == NULL) {
ERR(ctx, "blob is empty in blob.integer()");
return 0;
}
if ((unsigned)b->len >= sizeof(VCL_INT))
return *((VCL_INT *) b->priv);
for (int j = 0; j < b->len; j++)
i |= ((unsigned char *)b->priv)[j] << ((b->len - j - 1) * 8);
if (padding[0] == 'R')
......
......@@ -34,11 +34,19 @@ $Function BOOL same(BLOB, BLOB)
Returns true if and only if the two BLOB arguments are the same
object, i.e. they specify exactly the same region of memory.
If the BLOBs are both empty (length is 0 and/or the internal pointer
is NULL), then ``same()`` returns ``true``. If any non-empty BLOB
is compared to an empty BLOB, then ``same()`` returns ``false``.
$Function BOOL equal(BLOB, BLOB)
Returns true if and only if the two BLOB arguments have equal contents
(possibly in different memory regions).
As with ``same()``: If the BLOBs are both empty, then ``equal()``
returns ``true``. If any non-empty BLOB is compared to an empty BLOB,
then ``equal()`` returns ``false``.
$Function INT length(BLOB)
Returns the length of the BLOB.
......@@ -58,10 +66,10 @@ The value of the returned integer results from the bytes from the BLOB
in ascending order of addresses interpreted according to the
endianness of the system on which Varnish is running.
If the length of the BLOB is 0, then ``integer()`` returns 0 and emits
an error message to the Varnish log using the ``VCL_Error`` tag. If
this happens when ``integer()`` is called in ``vcl_init``, then the
VCL load fails with the error message. If it happens in any other VCL
If the BLOB is empty, then ``integer()`` returns 0 and emits an error
message to the Varnish log using the ``VCL_Error`` tag. If this
happens when ``integer()`` is called in ``vcl_init``, then the VCL
load fails with the error message. If it happens in any other VCL
subroutine, then VCL processing continues. Since 0 can be a legitimate
return value, you should monitor the Varnish log for the error.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment