[libvirt] [PATCHv2 RESEND 1/5] viruuid.h/c: Util method for finding uuid patterns in some strings
Ján Tomko
jtomko at redhat.com
Mon Sep 9 12:03:40 UTC 2013
On 09/02/2013 06:05 PM, Manuel VIVES wrote:
> ---
> src/libvirt_private.syms | 1 +
> src/util/viruuid.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++
> src/util/viruuid.h | 1 +
> 3 files changed, 81 insertions(+)
>
> @@ -333,3 +337,78 @@ int virGetHostUUID(unsigned char *uuid)
>
> return ret;
> }
> +
> +
> +/**
> + * virSearchUuid:
> + * Return the nth occurrence of a substring in sourceString which matches an uuid pattern
> + * If there is no substring, ret is not modified
> + *
> + * @sourceString: String to parse
> + * @occurrence: We will return the nth occurrence of uuid in substring, if equals to 0 (or negative), will return the first occurence
> + * @ret: nth occurrence substring matching an uuid pattern
> + * @code
> + char *source = "6853a496-1c10-472e-867a-8244937bd6f0 773ab075-4cd7-4fc2-8b6e-21c84e9cb391 bbb3c75c-d60f-43b0-b802-fd56b84a4222 60c04aa1-0375-4654-8d9f-e149d9885273 4548d465-9891-4c34-a184-3b1c34a26aa8";
> + char *ret1=NULL;
> + char *ret2=NULL;
> + char *ret3=NULL;
> + char *ret4=NULL;
> + virSearchUuid(source, 4,&ret1); //ret1 = "60c04aa1-0375-4654-8d9f-e149d9885273"
> + virSearchUuid(source, 0,&ret2); //ret2 = "6853a496-1c10-472e-867a-8244937bd6f0"
> + virSearchUuid(source, 1,&ret3); //ret3 = "6853a496-1c10-472e-867a-8244937bd6f0"
> + virSearchUuid(source, -4,&ret4); //ret4 = "6853a496-1c10-472e-867a-8244937bd6f0"
> + * @endcode
> + */
> +
> +char **
> +virSearchUuid(const char *sourceString, int occurrence,char **ret)
char ** func(..., char **ret) seems redundant.
Either drop the 'ret' parameter completely and return just char,
or change the return value to int (e.g. -1 = error, 0 = not found, 1 = found).
> +{
> + int position = ((occurrence -1) > 0) ? (occurrence -1) : 0;
> +
> + const char *uuidRegex = "([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})";
> + regex_t pregUuidBracket;
> + size_t i = 0;
> + size_t nmatch = 0;
> + regmatch_t *pmatch = NULL;
> + if (regcomp(&pregUuidBracket, uuidRegex, REG_EXTENDED) != 0) {
> + VIR_DEBUG("Error while compiling regular expression");
This should be virReportError.
> + goto cleanup;
and a return here, or you'll call regfree on an uninitialized variable.
> + }
> + nmatch = pregUuidBracket.re_nsub;
> + if (VIR_ALLOC_N(pmatch, nmatch) != 0) {
> + virReportOOMError();
VIR_ALLOC already reports an error.
> + goto cleanup;
> + }
> + while (i < (position+1)) {
You should exit the cycle on the first regexec failure, there's no point in
calling it again and again with the same arguments.
> + if (regexec(&pregUuidBracket, sourceString, nmatch, pmatch, 0) == 0) {
All this
> + char *substring = NULL;
> + int start = pmatch[0].rm_so;
> + int end = pmatch[0].rm_eo;
> + size_t size = end - start;
> + if (VIR_ALLOC_N(substring, (size + 1)) != 0) {
> + virReportOOMError();
> + goto cleanup;
> + }
> + if (substring) {
> + if (virStrncpy(substring, &sourceString[start], size, size + 1)) {
> + substring[size] = '\0';
> + if (VIR_STRDUP(*ret, substring) < 0) {
> + VIR_DEBUG("cannot duplicate %s", substring);
> + goto cleanup;
> + }
> + }
> + VIR_FREE(substring);
> + }
can be replaced by:
regoff_t start = pmatch[0].rm_so;
regoff_t end = pmatch[0].rm_eo;
if (VIR_STRNDUP(*ret, sourceString + start, end - start) < 0)
goto cleanup;
But even then, by copying every UUID to *ret, you'd leak the string buffer
allocated for every one except the last one.
> + sourceString = &sourceString[end];
> + }
> + ++i;
> + }
These three lines are redundant:
> + regfree(&pregUuidBracket);
> + VIR_FREE(pmatch);
> + return ret;
> +
> +cleanup:
> + regfree(&pregUuidBracket);
> + VIR_FREE(pmatch);
> + return ret;
> +}
And I'm sorry, but I have no opinion on the rest of the patches.
Jan
More information about the libvir-list
mailing list