Mageia Bugzilla – Attachment 12663 Details for
Bug 28815
provides/conflicts/requires/obsoletes not parsed properly when they contain square brackets
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
New Account
|
Forgot Password
[patch]
Patch adding the test and a fix making it pass
p (text/plain), 6.24 KB, created by
Pascal Terjan
on 2021-04-22 15:03:22 CEST
(
hide
)
Description:
Patch adding the test and a fix making it pass
Filename:
MIME Type:
Creator:
Pascal Terjan
Created:
2021-04-22 15:03:22 CEST
Size:
6.24 KB
patch
obsolete
>diff --git a/URPM.xs b/URPM.xs >index 0b31798..758922f 100644 >--- a/URPM.xs >+++ b/URPM.xs >@@ -377,6 +377,66 @@ callback_list_str_overlap(char *s, int slen, const char *name, rpmsenseFlags fla > return result; > } > >+struct parsed_sense { >+ char *name; >+ rpmsenseFlags flags; >+ char *evr; >+}; >+ >+static void free_parsed_sense(struct parsed_sense *ps) { >+ free(ps->name); >+ ps->name = NULL; >+ ps->flags = 0; >+ free(ps->evr); >+ ps->evr = NULL; >+} >+ >+// This parses things like 'ocamlx(bar)[== 42]' or 'ocaml-bar < 42' >+static int parse_sense(char *s, struct parsed_sense *ps) { >+ int l = strlen(s); >+ char *eon = NULL; >+ >+ if (l == 0) return -1; >+ >+ if (s[l-1] == ']') { >+ eon = strrchr(s, '['); >+ >+ if (eon == NULL || eon == s) { >+ // This is a strange one finishing with ] but without a [ before like >+ // "Provides: foo]" or something without a name before like >+ // "Provides: [foo]" >+ ps->name = strdup(s); >+ ps->flags = 0; >+ ps->evr = strdup(""); >+ return 0; >+ } >+ } >+ >+ if (eon == NULL) { >+ // This does not have [ ] at the end but could be in the form "gcc < 42" >+ eon = s; >+ while (*eon && *eon != ' ' && *eon != '<' && *eon != '>' && *eon != '=') ++eon; >+ } >+ >+ ps->name = strndup(s, eon-s); >+ ps->flags = 0; >+ l = strlen(eon); >+ s = eon; >+ while (*s) { >+ if (*s == ' ' || *s == '[' || *s == '*' || *s == ']'); >+ else if (*s == '<') ps->flags |= RPMSENSE_LESS; >+ else if (*s == '>') ps->flags |= RPMSENSE_GREATER; >+ else if (*s == '=') ps->flags |= RPMSENSE_EQUAL; >+ else break; >+ ++s; >+ --l; >+ } >+ ps->evr = strndup(s, l-1); >+ fprintf(stderr, "name=\"%s\" evr=\"%s\"\n", ps->name, ps->evr); >+ >+ return 0; >+} >+ > static int > return_list_str(char *s, const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_version, callback_list_str f, void *param) { > int count = 0; >@@ -394,21 +454,29 @@ return_list_str(char *s, const Header header, rpmTag tag_name, rpmTag tag_flags, > if (f(s, 0, NULL, 0, NULL, param)) > return -count; > } else { >- char *eos; >+ struct parsed_sense ops; > while(ps != NULL) { >- *ps = 0; eos = strchr(s, '['); if (!eos) eos = strchr(s, ' '); >- ++count; >- if (f(s, eos ? eos-s : ps-s, NULL, 0, NULL, param)) { >- *ps = '@'; >- return -count; >+ *ps = 0; >+ if (!parse_sense(s, &ops)) { >+ ++count; >+ if (f(ops.name, strlen(ops.name), NULL, 0, NULL, param)) { >+ *ps = '@'; >+ free_parsed_sense(&ops); >+ return -count; >+ } >+ free_parsed_sense(&ops); > } >- *ps = '@'; /* restore in memory modified char */ >+ *ps = '@'; > s = ps + 1; ps = strchr(s, '@'); > } >- eos = strchr(s, '['); if (!eos) eos = strchr(s, ' '); > ++count; >- if (f(s, eos ? eos-s : 0, NULL, 0, NULL, param)) >- return -count; >+ if (!parse_sense(s, &ops)) { >+ if (f(ops.name, strlen(ops.name), NULL, 0, NULL, param)) { >+ free_parsed_sense(&ops); >+ return -count; >+ } >+ free_parsed_sense(&ops); >+ } > } > } else if (header) { > struct rpmtd_s list, flags, list_evr; >@@ -1462,7 +1530,6 @@ static int get_e_v_r(URPM__Package pkg, int *epoch, char **version, char **relea > return 0; > } > >- > MODULE = URPM PACKAGE = URPM::Package PREFIX = Pkg_ > > void >@@ -1942,8 +2009,7 @@ Pkg_obsoletes_overlap(pkg, s) > provides_overlap = 1 > PREINIT: > struct cb_overlap_s os; >- char *eon = NULL; >- char eonc = '\0'; >+ struct parsed_sense ps; > rpmTag tag_name; > rpmTag tag_flags, tag_version; > CODE: >@@ -1959,33 +2025,18 @@ Pkg_obsoletes_overlap(pkg, s) > tag_version = RPMTAG_OBSOLETEVERSION; > break; > } >- os.name = s; >- os.flags = 0; >- while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; >- if (*s) { >- eon = s; >- while (*s) { >- if (*s == ' ' || *s == '[' || *s == '*' || *s == ']'); >- else if (*s == '<') os.flags |= RPMSENSE_LESS; >- else if (*s == '>') os.flags |= RPMSENSE_GREATER; >- else if (*s == '=') os.flags |= RPMSENSE_EQUAL; >- else break; >- ++s; >- } >- os.evr = s; >- } else >- os.evr = ""; >- os.direction = ix == 0 ? -1 : 1; >- /* mark end of name */ >- if (eon) { >- eonc = *eon; >- *eon = 0; >+ if (parse_sense(s, &ps)) { >+ RETVAL = -1; >+ } else { >+ os.name = ps.name; >+ os.flags = ps.flags; >+ os.evr = ps.evr; >+ os.direction = ix == 0 ? -1 : 1; >+ /* return_list_str returns a negative value is the callback has returned non-zero */ >+ RETVAL = return_list_str(ix == 0 ? pkg->obsoletes : pkg->provides, pkg->h, tag_name, tag_flags, tag_version, >+ callback_list_str_overlap, &os) < 0; >+ free_parsed_sense(&ps); > } >- /* return_list_str returns a negative value is the callback has returned non-zero */ >- RETVAL = return_list_str(ix == 0 ? pkg->obsoletes : pkg->provides, pkg->h, tag_name, tag_flags, tag_version, >- callback_list_str_overlap, &os) < 0; >- /* restore end of name */ >- if (eon) *eon = eonc; > OUTPUT: > RETVAL > >diff --git a/t/synthesis.t b/t/synthesis.t >index 8246b36..1cc9071 100644 >--- a/t/synthesis.t >+++ b/t/synthesis.t >@@ -2,7 +2,7 @@ > > use strict ; > use warnings ; >-use Test::More tests => 95; >+use Test::More tests => 101; > use URPM; > > chdir 't' if -d 't'; >@@ -27,7 +27,18 @@ $s =~ s/-devel//g; > print $f $s; > close $f; > >-END { unlink $file1, $file2 } >+$s = <<'EOF'; >+@provides@python3-fonttools+ufo[== 4.18.2-4.mga9]@python3dist(fonttools[ufo])[== 4.18.2] >+@summary@Metapackage for python3-fonttools: ufo extras >+@info@python3-fonttools+ufo-4.18.2-4.mga9.noarch@0@221683@Development/Other >+EOF >+ >+my $file3 = 'synthesis.squarebrackets.cz'; >+open $f, "| gzip -9 >$file3"; >+print $f $s; >+close $f; >+ >+END { unlink $file1, $file2, $file3 } > > my $a = URPM->new; > ok($a); >@@ -161,3 +172,15 @@ ok($requires[8] eq 'rpmlib(CompressedFileNames)'); > @provides = $pkg->provides_nosense; > ok(@provides == 1); > ok($provides[0] eq 'glibc-devel'); >+ >+my $b = URPM->new; >+$b->parse_synthesis($file3); >+$pkg = $b->{depslist}[0]; >+ok($pkg); >+is($pkg->name, 'python3-fonttools+ufo'); >+@provides = $pkg->provides; >+is(@provides, 2); >+is($provides[1], 'python3dist(fonttools[ufo])[== 4.18.2]'); >+@provides = $pkg->provides_nosense; >+is(@provides, 2); >+is($provides[1], 'python3dist(fonttools[ufo])');
diff --git a/URPM.xs b/URPM.xs index 0b31798..758922f 100644 --- a/URPM.xs +++ b/URPM.xs @@ -377,6 +377,66 @@ callback_list_str_overlap(char *s, int slen, const char *name, rpmsenseFlags fla return result; } +struct parsed_sense { + char *name; + rpmsenseFlags flags; + char *evr; +}; + +static void free_parsed_sense(struct parsed_sense *ps) { + free(ps->name); + ps->name = NULL; + ps->flags = 0; + free(ps->evr); + ps->evr = NULL; +} + +// This parses things like 'ocamlx(bar)[== 42]' or 'ocaml-bar < 42' +static int parse_sense(char *s, struct parsed_sense *ps) { + int l = strlen(s); + char *eon = NULL; + + if (l == 0) return -1; + + if (s[l-1] == ']') { + eon = strrchr(s, '['); + + if (eon == NULL || eon == s) { + // This is a strange one finishing with ] but without a [ before like + // "Provides: foo]" or something without a name before like + // "Provides: [foo]" + ps->name = strdup(s); + ps->flags = 0; + ps->evr = strdup(""); + return 0; + } + } + + if (eon == NULL) { + // This does not have [ ] at the end but could be in the form "gcc < 42" + eon = s; + while (*eon && *eon != ' ' && *eon != '<' && *eon != '>' && *eon != '=') ++eon; + } + + ps->name = strndup(s, eon-s); + ps->flags = 0; + l = strlen(eon); + s = eon; + while (*s) { + if (*s == ' ' || *s == '[' || *s == '*' || *s == ']'); + else if (*s == '<') ps->flags |= RPMSENSE_LESS; + else if (*s == '>') ps->flags |= RPMSENSE_GREATER; + else if (*s == '=') ps->flags |= RPMSENSE_EQUAL; + else break; + ++s; + --l; + } + ps->evr = strndup(s, l-1); + fprintf(stderr, "name=\"%s\" evr=\"%s\"\n", ps->name, ps->evr); + + return 0; +} + static int return_list_str(char *s, const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_version, callback_list_str f, void *param) { int count = 0; @@ -394,21 +454,29 @@ return_list_str(char *s, const Header header, rpmTag tag_name, rpmTag tag_flags, if (f(s, 0, NULL, 0, NULL, param)) return -count; } else { - char *eos; + struct parsed_sense ops; while(ps != NULL) { - *ps = 0; eos = strchr(s, '['); if (!eos) eos = strchr(s, ' '); - ++count; - if (f(s, eos ? eos-s : ps-s, NULL, 0, NULL, param)) { - *ps = '@'; - return -count; + *ps = 0; + if (!parse_sense(s, &ops)) { + ++count; + if (f(ops.name, strlen(ops.name), NULL, 0, NULL, param)) { + *ps = '@'; + free_parsed_sense(&ops); + return -count; + } + free_parsed_sense(&ops); } - *ps = '@'; /* restore in memory modified char */ + *ps = '@'; s = ps + 1; ps = strchr(s, '@'); } - eos = strchr(s, '['); if (!eos) eos = strchr(s, ' '); ++count; - if (f(s, eos ? eos-s : 0, NULL, 0, NULL, param)) - return -count; + if (!parse_sense(s, &ops)) { + if (f(ops.name, strlen(ops.name), NULL, 0, NULL, param)) { + free_parsed_sense(&ops); + return -count; + } + free_parsed_sense(&ops); + } } } else if (header) { struct rpmtd_s list, flags, list_evr; @@ -1462,7 +1530,6 @@ static int get_e_v_r(URPM__Package pkg, int *epoch, char **version, char **relea return 0; } - MODULE = URPM PACKAGE = URPM::Package PREFIX = Pkg_ void @@ -1942,8 +2009,7 @@ Pkg_obsoletes_overlap(pkg, s) provides_overlap = 1 PREINIT: struct cb_overlap_s os; - char *eon = NULL; - char eonc = '\0'; + struct parsed_sense ps; rpmTag tag_name; rpmTag tag_flags, tag_version; CODE: @@ -1959,33 +2025,18 @@ Pkg_obsoletes_overlap(pkg, s) tag_version = RPMTAG_OBSOLETEVERSION; break; } - os.name = s; - os.flags = 0; - while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; - if (*s) { - eon = s; - while (*s) { - if (*s == ' ' || *s == '[' || *s == '*' || *s == ']'); - else if (*s == '<') os.flags |= RPMSENSE_LESS; - else if (*s == '>') os.flags |= RPMSENSE_GREATER; - else if (*s == '=') os.flags |= RPMSENSE_EQUAL; - else break; - ++s; - } - os.evr = s; - } else - os.evr = ""; - os.direction = ix == 0 ? -1 : 1; - /* mark end of name */ - if (eon) { - eonc = *eon; - *eon = 0; + if (parse_sense(s, &ps)) { + RETVAL = -1; + } else { + os.name = ps.name; + os.flags = ps.flags; + os.evr = ps.evr; + os.direction = ix == 0 ? -1 : 1; + /* return_list_str returns a negative value is the callback has returned non-zero */ + RETVAL = return_list_str(ix == 0 ? pkg->obsoletes : pkg->provides, pkg->h, tag_name, tag_flags, tag_version, + callback_list_str_overlap, &os) < 0; + free_parsed_sense(&ps); } - /* return_list_str returns a negative value is the callback has returned non-zero */ - RETVAL = return_list_str(ix == 0 ? pkg->obsoletes : pkg->provides, pkg->h, tag_name, tag_flags, tag_version, - callback_list_str_overlap, &os) < 0; - /* restore end of name */ - if (eon) *eon = eonc; OUTPUT: RETVAL diff --git a/t/synthesis.t b/t/synthesis.t index 8246b36..1cc9071 100644 --- a/t/synthesis.t +++ b/t/synthesis.t @@ -2,7 +2,7 @@ use strict ; use warnings ; -use Test::More tests => 95; +use Test::More tests => 101; use URPM; chdir 't' if -d 't'; @@ -27,7 +27,18 @@ $s =~ s/-devel//g; print $f $s; close $f; -END { unlink $file1, $file2 } +$s = <<'EOF'; +@provides@python3-fonttools+ufo[== 4.18.2-4.mga9]@python3dist(fonttools[ufo])[== 4.18.2] +@summary@Metapackage for python3-fonttools: ufo extras +@info@python3-fonttools+ufo-4.18.2-4.mga9.noarch@0@221683@Development/Other +EOF + +my $file3 = 'synthesis.squarebrackets.cz'; +open $f, "| gzip -9 >$file3"; +print $f $s; +close $f; + +END { unlink $file1, $file2, $file3 } my $a = URPM->new; ok($a); @@ -161,3 +172,15 @@ ok($requires[8] eq 'rpmlib(CompressedFileNames)'); @provides = $pkg->provides_nosense; ok(@provides == 1); ok($provides[0] eq 'glibc-devel'); + +my $b = URPM->new; +$b->parse_synthesis($file3); +$pkg = $b->{depslist}[0]; +ok($pkg); +is($pkg->name, 'python3-fonttools+ufo'); +@provides = $pkg->provides; +is(@provides, 2); +is($provides[1], 'python3dist(fonttools[ufo])[== 4.18.2]'); +@provides = $pkg->provides_nosense; +is(@provides, 2); +is($provides[1], 'python3dist(fonttools[ufo])');
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 28815
:
12658
| 12663