From ccdb28b761bbb37ff4f4f26dae494e5ea01562c5 Mon Sep 17 00:00:00 2001 From: Matthew Booth Date: Tue, 18 Oct 2011 13:30:40 +0100 Subject: [PATCH] inspect: Don't assume number of captures in match functions It is possible for the pcre library to return a variable number of captures for a single regular expression. e.g.: ^/dev/(cciss/c\d+d\d+)(?:p(\d+))?$ This will return either 1 or 2 captures depending on whether the device has a partition suffix. The current match wrappers don't allow for this, and require that a predictable number of matches are returned. This change updates match, match1, match2, and match3 to ignore the specific number of matches returned. Instead, any returned captures are assigned to the given arguments, and any remaining arguments are set to NULL. (cherry picked from commit f5c9f0e9ee1729b1260cef3e51ca91936e1868c4) --- src/match.c | 43 +++++++++++++------------------------------ 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/src/match.c b/src/match.c index 68b2d4b..6038e41 100644 --- a/src/match.c +++ b/src/match.c @@ -39,12 +39,6 @@ guestfs___match (guestfs_h *g, const char *str, const pcre *re) r = pcre_exec (re, NULL, str, len, 0, 0, vec, sizeof vec / sizeof vec[0]); if (r == PCRE_ERROR_NOMATCH) return 0; - if (r != 1) { - /* Internal error -- should not happen. */ - warning (g, "%s: %s: pcre_exec returned unexpected error code %d when matching against the string \"%s\"\n", - __FILE__, __func__, r, str); - return 0; - } return 1; } @@ -62,14 +56,8 @@ guestfs___match1 (guestfs_h *g, const char *str, const pcre *re) r = pcre_exec (re, NULL, str, len, 0, 0, vec, sizeof vec / sizeof vec[0]); if (r == PCRE_ERROR_NOMATCH) return NULL; - if (r != 2) { - /* Internal error -- should not happen. */ - warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"", - __FILE__, __func__, r, str); - return NULL; - } - return safe_strndup (g, &str[vec[2]], vec[3]-vec[2]); + return r == 2 ? safe_strndup (g, &str[vec[2]], vec[3]-vec[2]) : NULL; } /* Match a regular expression which contains exactly two captures. */ @@ -83,15 +71,12 @@ guestfs___match2 (guestfs_h *g, const char *str, const pcre *re, r = pcre_exec (re, NULL, str, len, 0, 0, vec, 30); if (r == PCRE_ERROR_NOMATCH) return 0; - if (r != 3) { - /* Internal error -- should not happen. */ - warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"", - __FILE__, __func__, r, str); - return 0; - } - *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]); - *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]); + *ret1 = NULL; + *ret2 = NULL; + + if (r > 1) *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]); + if (r > 2) *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]); return 1; } @@ -107,16 +92,14 @@ guestfs___match3 (guestfs_h *g, const char *str, const pcre *re, r = pcre_exec (re, NULL, str, len, 0, 0, vec, 30); if (r == PCRE_ERROR_NOMATCH) return 0; - if (r != 4) { - /* Internal error -- should not happen. */ - warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"", - __FILE__, __func__, r, str); - return 0; - } - *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]); - *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]); - *ret3 = safe_strndup (g, &str[vec[6]], vec[7]-vec[6]); + *ret1 = NULL; + *ret2 = NULL; + *ret3 = NULL; + + if (r > 1) *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]); + if (r > 2) *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]); + if (r > 3) *ret3 = safe_strndup (g, &str[vec[6]], vec[7]-vec[6]); return 1; } -- 1.8.3.1