From: Willy Tarreau Date: Tue, 9 Aug 2016 09:49:20 +0000 (+0200) Subject: MINOR: sample: provide smp_is_rw() and smp_make_rw() X-Git-Tag: v1.7-dev4~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77128f585ce682ebc14f063f4b91c8cdecf4e4b8;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/include/proto/sample.h b/include/proto/sample.h index 9b5d026169..ecb2eb4977 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 */