From 77128f585ce682ebc14f063f4b91c8cdecf4e4b8 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 9 Aug 2016 11:49:20 +0200 Subject: [PATCH] MINOR: sample: provide smp_is_rw() and smp_make_rw() At some places, smp_dup() is inappropriately called to ensure a modification is possible while in fact we only need to ensure the sample may be modified in place. Let's provide smp_is_rw() to check for this capability and smp_make_rw() to perform the smp_dup() when it is not the case. Note that smp_is_rw() will also try to add the trailing zero on strings when needed if possible, to avoid a useless duplication. --- include/proto/sample.h | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/include/proto/sample.h b/include/proto/sample.h index 9b5d02616..ecb2eb497 100644 --- a/include/proto/sample.h +++ b/include/proto/sample.h @@ -118,4 +118,48 @@ int smp_make_safe(struct sample *smp) return smp && (smp_is_safe(smp) || smp_dup(smp)); } +/* Returns 1 if a sample may be safely modified in place. It performs a few + * checks on the string length versus size, same for the binary version, and + * ensures that strings are properly terminated by a zero, and of course that + * the size is allocate and that the SMP_F_CONST flag is not set. If only the + * trailing zero is missing, it is appended. Otherwise it returns 0, meaning + * the caller may need to call smp_dup() before going further. + */ +static inline +int smp_is_rw(struct sample *smp) +{ + if (smp->flags & SMP_F_CONST) + return 0; + + switch (smp->data.type) { + case SMP_T_STR: + if (!smp->data.u.str.size || + smp->data.u.str.len < 0 || + smp->data.u.str.len >= smp->data.u.str.size) + return 0; + + if (smp->data.u.str.str[smp->data.u.str.len] != 0) + smp->data.u.str.str[smp->data.u.str.len] = 0; + return 1; + + case SMP_T_BIN: + return smp->data.u.str.size && + smp->data.u.str.len >= 0 && + smp->data.u.str.len <= smp->data.u.str.size; + + default: + return 1; + } +} + +/* checks that a sample may freely be modified, or duplicates it to normalize + * it and make it R/W. Returns 1 on success, 0 if the sample must not be used. + * The function also checks for NULL to simplify the calling code. + */ +static inline +int smp_make_rw(struct sample *smp) +{ + return smp && (smp_is_rw(smp) || smp_dup(smp)); +} + #endif /* _PROTO_SAMPLE_H */