[libvirt] [PATCH 10/12] util: use GRegex in virStringSearch

Ján Tomko posted 12 patches 6 years, 2 months ago
[libvirt] [PATCH 10/12] util: use GRegex in virStringSearch
Posted by Ján Tomko 6 years, 2 months ago
Signed-off-by: Ján Tomko <jtomko@redhat.com>
---
 src/util/virstring.c | 31 ++++++++++++++-----------------
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/src/util/virstring.c b/src/util/virstring.c
index 283cf8c8d8..3da793c87a 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -1017,29 +1017,27 @@ virStringSearch(const char *str,
                 size_t max_matches,
                 char ***matches)
 {
-    regex_t re;
-    regmatch_t rem;
+    g_autoptr(GRegex) regex = NULL;
+    g_autoptr(GError) err = NULL;
+    g_autoptr(GMatchInfo) info = NULL;
     size_t nmatches = 0;
     ssize_t ret = -1;
-    int rv = -1;
 
     *matches = NULL;
 
     VIR_DEBUG("search '%s' for '%s'", str, regexp);
 
-    if ((rv = regcomp(&re, regexp, REG_EXTENDED)) != 0) {
-        char error[100];
-        regerror(rv, &re, error, sizeof(error));
+    regex = g_regex_new(regexp, 0, 0, &err);
+    if (!regex) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Error while compiling regular expression '%s': %s"),
-                       regexp, error);
+                       _("Failed to compile regex %s"), err->message);
         return -1;
     }
 
-    if (re.re_nsub != 1) {
+    if (g_regex_get_capture_count(regex) != 1) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Regular expression '%s' must have exactly 1 match group, not %zu"),
-                       regexp, re.re_nsub);
+                       _("Regular expression '%s' must have exactly 1 match group, not %d"),
+                       regexp, g_regex_get_capture_count(regex));
         goto cleanup;
     }
 
@@ -1051,28 +1049,27 @@ virStringSearch(const char *str,
 
     while ((nmatches - 1) < max_matches) {
         char *match;
+        int endpos;
 
-        if (regexec(&re, str, 1, &rem, 0) != 0)
+        if (!g_regex_match(regex, str, 0, &info))
             break;
 
         if (VIR_EXPAND_N(*matches, nmatches, 1) < 0)
             goto cleanup;
 
-        if (VIR_STRNDUP(match, str + rem.rm_so,
-                        rem.rm_eo - rem.rm_so) < 0)
-            goto cleanup;
+        match = g_match_info_fetch(info, 1);
 
         VIR_DEBUG("Got '%s'", match);
 
         (*matches)[nmatches-2] = match;
 
-        str = str + rem.rm_eo;
+        g_match_info_fetch_pos(info, 1, NULL, &endpos);
+        str += endpos;
     }
 
     ret = nmatches - 1; /* don't count the trailing null */
 
  cleanup:
-    regfree(&re);
     if (ret < 0) {
         virStringListFree(*matches);
         *matches = NULL;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 10/12] util: use GRegex in virStringSearch
Posted by Peter Krempa 6 years, 2 months ago
On Wed, Nov 13, 2019 at 16:48:51 +0100, Ján Tomko wrote:
> Signed-off-by: Ján Tomko <jtomko@redhat.com>
> ---
>  src/util/virstring.c | 31 ++++++++++++++-----------------
>  1 file changed, 14 insertions(+), 17 deletions(-)
> 
> diff --git a/src/util/virstring.c b/src/util/virstring.c
> index 283cf8c8d8..3da793c87a 100644
> --- a/src/util/virstring.c
> +++ b/src/util/virstring.c
> @@ -1017,29 +1017,27 @@ virStringSearch(const char *str,
>                  size_t max_matches,
>                  char ***matches)
>  {
> -    regex_t re;
> -    regmatch_t rem;
> +    g_autoptr(GRegex) regex = NULL;
> +    g_autoptr(GError) err = NULL;
> +    g_autoptr(GMatchInfo) info = NULL;
>      size_t nmatches = 0;
>      ssize_t ret = -1;
> -    int rv = -1;
>  
>      *matches = NULL;
>  
>      VIR_DEBUG("search '%s' for '%s'", str, regexp);
>  
> -    if ((rv = regcomp(&re, regexp, REG_EXTENDED)) != 0) {
> -        char error[100];
> -        regerror(rv, &re, error, sizeof(error));
> +    regex = g_regex_new(regexp, 0, 0, &err);
> +    if (!regex) {
>          virReportError(VIR_ERR_INTERNAL_ERROR,
> -                       _("Error while compiling regular expression '%s': %s"),
> -                       regexp, error);
> +                       _("Failed to compile regex %s"), err->message);
>          return -1;
>      }
>  
> -    if (re.re_nsub != 1) {
> +    if (g_regex_get_capture_count(regex) != 1) {
>          virReportError(VIR_ERR_INTERNAL_ERROR,
> -                       _("Regular expression '%s' must have exactly 1 match group, not %zu"),
> -                       regexp, re.re_nsub);
> +                       _("Regular expression '%s' must have exactly 1 match group, not %d"),
> +                       regexp, g_regex_get_capture_count(regex));
>          goto cleanup;
>      }
>  
> @@ -1051,28 +1049,27 @@ virStringSearch(const char *str,
>  
>      while ((nmatches - 1) < max_matches) {
>          char *match;
> +        int endpos;
>  
> -        if (regexec(&re, str, 1, &rem, 0) != 0)
> +        if (!g_regex_match(regex, str, 0, &info))

info is overwritten and leaked

>              break;
>  
>          if (VIR_EXPAND_N(*matches, nmatches, 1) < 0)
>              goto cleanup;
>  
> -        if (VIR_STRNDUP(match, str + rem.rm_so,
> -                        rem.rm_eo - rem.rm_so) < 0)
> -            goto cleanup;
> +        match = g_match_info_fetch(info, 1);
>  
>          VIR_DEBUG("Got '%s'", match);
>  
>          (*matches)[nmatches-2] = match;
>  
> -        str = str + rem.rm_eo;
> +        g_match_info_fetch_pos(info, 1, NULL, &endpos);
> +        str += endpos;
>      }
>  
>      ret = nmatches - 1; /* don't count the trailing null */
>  
>   cleanup:
> -    regfree(&re);
>      if (ret < 0) {
>          virStringListFree(*matches);
>          *matches = NULL;

With the memleak resolved:

Reviewed-by: Peter Krempa <pkrempa@redhat.com>

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list