[pacman-dev] Add str_endswith() utility function

Message ID 20200421184210.46780-1-anatol.pomozov@gmail.com
State Superseded, archived
Headers show
Series [pacman-dev] Add str_endswith() utility function | expand

Commit Message

Anatol Pomozov April 21, 2020, 6:42 p.m. UTC
It provides an easy way to check whether a string ends with a given
suffix.

Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com>
---
 src/common/util-common.c | 18 ++++++++++++++++++
 src/common/util-common.h |  2 ++
 2 files changed, 20 insertions(+)

Comments

Allan McRae April 29, 2020, 3:43 a.m. UTC | #1
On 22/4/20 4:42 am, Anatol Pomozov wrote:
> It provides an easy way to check whether a string ends with a given
> suffix.
> 

Note: "pkg.sig" is a valid package name with signature file
"pkg.sig.sig"....

> Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com>
> ---
>  src/common/util-common.c | 18 ++++++++++++++++++
>  src/common/util-common.h |  2 ++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/src/common/util-common.c b/src/common/util-common.c
> index 7d43ac0d..11ffc705 100644
> --- a/src/common/util-common.c
> +++ b/src/common/util-common.c

Why util-common?   Is this being used in both pacman and libalpm?

> @@ -198,6 +198,24 @@ char *strndup(const char *s, size_t n)
>  }
>  #endif
>  
> +/** Helper function for check whether a string ends with a given suffix
> + * @param str a string
> + * @param suffix we want to check
> + * @return 0 in case if the given string does not end with the suffix,
> + *    a non-zero value otherwise.
> + */
> +int str_endswith(const char *str, const char *suffix)

str_ends_with

> +{
> +	int str_len = strlen(str);
> +	int suffix_len = strlen(suffix);
> +
> +	if(suffix_len > str_len) {

>=

I am assuming you want to match a suffix and not the entire string.

> +		return 0;
> +	}
> +
> +	return !strcmp(str + str_len - suffix_len, suffix);

return (strcmp(str + str_len - suffix_len, suffix) == 0)

> +}
> +
>  void wordsplit_free(char **ws)
>  {
>  	if(ws) {
> diff --git a/src/common/util-common.h b/src/common/util-common.h
> index 483d5da4..6b66be3e 100644
> --- a/src/common/util-common.h
> +++ b/src/common/util-common.h
> @@ -35,6 +35,8 @@ char **wordsplit(const char *str);
>  
>  size_t strtrim(char *str);
>  
> +int str_endswith(const char *str, const char *suffix);
> +
>  #ifndef HAVE_STRNDUP
>  char *strndup(const char *s, size_t n);
>  #endif
>
Anatol Pomozov May 5, 2020, 10:56 p.m. UTC | #2
Hi

On Tue, Apr 28, 2020 at 8:43 PM Allan McRae <allan@archlinux.org> wrote:
>
> On 22/4/20 4:42 am, Anatol Pomozov wrote:
> > It provides an easy way to check whether a string ends with a given
> > suffix.
> >
>
> Note: "pkg.sig" is a valid package name with signature file
> "pkg.sig.sig"....

But *.pkg.sig.sig could be a valid package name as well, right?

If package can have any suffix (like pkg.sig.sig or pkg.sig.sig.sig or
...) then there seems no way to guess signature from its filename. And
the only way to track if a payload is signature file is to add an
extra field to "struct dload_payload {".

If so then this function will not be needed at all.

> > Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com>
> > ---
> >  src/common/util-common.c | 18 ++++++++++++++++++
> >  src/common/util-common.h |  2 ++
> >  2 files changed, 20 insertions(+)
> >
> > diff --git a/src/common/util-common.c b/src/common/util-common.c
> > index 7d43ac0d..11ffc705 100644
> > --- a/src/common/util-common.c
> > +++ b/src/common/util-common.c
>
> Why util-common?   Is this being used in both pacman and libalpm?

There are 2 places where I check if file is a signature:
lib/libalpm/dload.c:880:
if(str_endswith(payload->destfile_name, ".sig")) {
src/pacman/callback.c:1004:     if(str_endswith(filename, ".sig")) {

Thus we need to move the function to a place shared both by ALPM and pacman.

>
> > @@ -198,6 +198,24 @@ char *strndup(const char *s, size_t n)
> >  }
> >  #endif
> >
> > +/** Helper function for check whether a string ends with a given suffix
> > + * @param str a string
> > + * @param suffix we want to check
> > + * @return 0 in case if the given string does not end with the suffix,
> > + *    a non-zero value otherwise.
> > + */
> > +int str_endswith(const char *str, const char *suffix)
>
> str_ends_with
> > +{
> > +     int str_len = strlen(str);
> > +     int suffix_len = strlen(suffix);
> > +
> > +     if(suffix_len > str_len) {
>
> >=
>
> I am assuming you want to match a suffix and not the entire string.

A string S is a suffix of itself. Thus str_endswith("A", "A") should
return true. This is how other languages/libraries work e.g. Golang
strings.HasSuffix() https://play.golang.org/p/OC8D0qruNuj

>
> > +             return 0;
> > +     }
> > +
> > +     return !strcmp(str + str_len - suffix_len, suffix);
>
> return (strcmp(str + str_len - suffix_len, suffix) == 0)
>
> > +}
> > +
> >  void wordsplit_free(char **ws)
> >  {
> >       if(ws) {
> > diff --git a/src/common/util-common.h b/src/common/util-common.h
> > index 483d5da4..6b66be3e 100644
> > --- a/src/common/util-common.h
> > +++ b/src/common/util-common.h
> > @@ -35,6 +35,8 @@ char **wordsplit(const char *str);
> >
> >  size_t strtrim(char *str);
> >
> > +int str_endswith(const char *str, const char *suffix);
> > +
> >  #ifndef HAVE_STRNDUP
> >  char *strndup(const char *s, size_t n);
> >  #endif
> >

Patch

diff --git a/src/common/util-common.c b/src/common/util-common.c
index 7d43ac0d..11ffc705 100644
--- a/src/common/util-common.c
+++ b/src/common/util-common.c
@@ -198,6 +198,24 @@  char *strndup(const char *s, size_t n)
 }
 #endif
 
+/** Helper function for check whether a string ends with a given suffix
+ * @param str a string
+ * @param suffix we want to check
+ * @return 0 in case if the given string does not end with the suffix,
+ *    a non-zero value otherwise.
+ */
+int str_endswith(const char *str, const char *suffix)
+{
+	int str_len = strlen(str);
+	int suffix_len = strlen(suffix);
+
+	if(suffix_len > str_len) {
+		return 0;
+	}
+
+	return !strcmp(str + str_len - suffix_len, suffix);
+}
+
 void wordsplit_free(char **ws)
 {
 	if(ws) {
diff --git a/src/common/util-common.h b/src/common/util-common.h
index 483d5da4..6b66be3e 100644
--- a/src/common/util-common.h
+++ b/src/common/util-common.h
@@ -35,6 +35,8 @@  char **wordsplit(const char *str);
 
 size_t strtrim(char *str);
 
+int str_endswith(const char *str, const char *suffix);
+
 #ifndef HAVE_STRNDUP
 char *strndup(const char *s, size_t n);
 #endif