1 |
commit: 89a388678c4975b541d24931b0916e2959ed70be |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Apr 5 12:10:26 2018 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Apr 5 12:10:26 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=89a38867 |
7 |
|
8 |
atom_explode: fix parsing of some valid corner cases |
9 |
|
10 |
Extract the version part of the atom, such that we can more reliably |
11 |
parse the version components without worrying about accidentially taking |
12 |
parts of the package name. |
13 |
|
14 |
Bug: https://bugs.gentoo.org/526596 |
15 |
|
16 |
libq/atom_explode.c | 78 +++++++++++++++++++++++++++++------------------------ |
17 |
tests/qatom/dotest | 13 ++++++--- |
18 |
2 files changed, 53 insertions(+), 38 deletions(-) |
19 |
|
20 |
diff --git a/libq/atom_explode.c b/libq/atom_explode.c |
21 |
index 1b81909..e52f149 100644 |
22 |
--- a/libq/atom_explode.c |
23 |
+++ b/libq/atom_explode.c |
24 |
@@ -147,7 +147,7 @@ atom_explode(const char *atom) |
25 |
} |
26 |
strcpy(ret->CATEGORY, atom); |
27 |
|
28 |
- /* eat file name crap */ |
29 |
+ /* eat file name crap when given an (autocompleted) path */ |
30 |
if ((ptr = strstr(ret->CATEGORY, ".ebuild")) != NULL) |
31 |
*ptr = '\0'; |
32 |
|
33 |
@@ -172,11 +172,12 @@ atom_explode(const char *atom) |
34 |
} |
35 |
} |
36 |
|
37 |
- /* break up the CATEOGRY and PVR */ |
38 |
+ /* break up the CATEGORY and PVR */ |
39 |
if ((ptr = strrchr(ret->CATEGORY, '/')) != NULL) { |
40 |
ret->PN = ptr + 1; |
41 |
*ptr = '\0'; |
42 |
- /* eat extra crap in case it exists */ |
43 |
+ /* eat extra crap in case it exists, this is a feature to allow |
44 |
+ * /path/to/pkg.ebuild */ |
45 |
if ((ptr = strrchr(ret->CATEGORY, '/')) != NULL) |
46 |
ret->CATEGORY = ptr + 1; |
47 |
} else { |
48 |
@@ -184,9 +185,28 @@ atom_explode(const char *atom) |
49 |
ret->CATEGORY = NULL; |
50 |
} |
51 |
|
52 |
+ /* CATEGORY should be all set here, PN contains everything up to |
53 |
+ * SLOT, REPO or '*' |
54 |
+ * PN must not end in a hyphen followed by anything matching version |
55 |
+ * syntax, version syntax starts with a number, so "-[0-9]" is a |
56 |
+ * separator from PN to PV* */ |
57 |
+ |
58 |
+ ptr = ret->PN; |
59 |
+ while ((ptr = strchr(ptr, '-')) != NULL) { |
60 |
+ ptr++; |
61 |
+ if (*ptr >= '0' && *ptr <= '9') |
62 |
+ break; |
63 |
+ } |
64 |
+ |
65 |
+ if (ptr == NULL) { |
66 |
+ /* atom has no version, this is it */ |
67 |
+ return ret; |
68 |
+ } |
69 |
+ ret->PV = ptr; |
70 |
+ |
71 |
/* find -r# */ |
72 |
- ptr = ret->PN + strlen(ret->PN) - 1; |
73 |
- while (*ptr && ptr > ret->PN) { |
74 |
+ ptr = ret->PV + strlen(ret->PV) - 1; |
75 |
+ while (*ptr && ptr > ret->PV) { |
76 |
if (!isdigit(*ptr)) { |
77 |
if (ptr[0] == 'r' && ptr[-1] == '-') { |
78 |
ret->PR_int = atoi(ptr + 1); |
79 |
@@ -197,39 +217,35 @@ atom_explode(const char *atom) |
80 |
--ptr; |
81 |
} |
82 |
strcpy(ret->P, ret->PN); |
83 |
+ ret->PV[-1] = '\0'; |
84 |
|
85 |
/* break out all the suffixes */ |
86 |
sidx = 0; |
87 |
ret->suffixes = xrealloc(ret->suffixes, sizeof(atom_suffix) * (sidx + 1)); |
88 |
ret->suffixes[sidx].sint = 0; |
89 |
ret->suffixes[sidx].suffix = VER_NORM; |
90 |
- while ((ptr = strrchr(ret->PN, '_')) != NULL) { |
91 |
+ ptr = ret->PV + strlen(ret->PV) - 1; |
92 |
+ while (ptr-- > ret->PV) { |
93 |
+ if (*ptr != '_') |
94 |
+ continue; |
95 |
for (idx = 0; idx < ARRAY_SIZE(atom_suffixes_str); ++idx) { |
96 |
- if (strncmp(ptr, atom_suffixes_str[idx], strlen(atom_suffixes_str[idx]))) |
97 |
+ if (strncmp(ptr, atom_suffixes_str[idx], |
98 |
+ strlen(atom_suffixes_str[idx]))) |
99 |
continue; |
100 |
|
101 |
- /* check this is a real suffix and not _p hitting mod_perl */ |
102 |
- char *tmp_ptr = ptr; |
103 |
- tmp_ptr += strlen(atom_suffixes_str[idx]); |
104 |
- ret->suffixes[sidx].sint = atoll(tmp_ptr); |
105 |
- while (isdigit(*tmp_ptr)) |
106 |
- ++tmp_ptr; |
107 |
- if (*tmp_ptr) |
108 |
- goto no_more_suffixes; |
109 |
+ ret->suffixes[sidx].sint = |
110 |
+ atoll(ptr + strlen(atom_suffixes_str[idx])); |
111 |
ret->suffixes[sidx].suffix = idx; |
112 |
|
113 |
++sidx; |
114 |
- *ptr = '\0'; |
115 |
|
116 |
- ret->suffixes = xrealloc(ret->suffixes, sizeof(atom_suffix) * (sidx + 1)); |
117 |
+ ret->suffixes = xrealloc(ret->suffixes, |
118 |
+ sizeof(atom_suffix) * (sidx + 1)); |
119 |
ret->suffixes[sidx].sint = 0; |
120 |
ret->suffixes[sidx].suffix = VER_NORM; |
121 |
break; |
122 |
} |
123 |
- if (*ptr) |
124 |
- break; |
125 |
} |
126 |
- no_more_suffixes: |
127 |
if (sidx) |
128 |
--sidx; |
129 |
for (idx = 0; idx < sidx; ++idx, --sidx) { |
130 |
@@ -238,35 +254,27 @@ atom_explode(const char *atom) |
131 |
ret->suffixes[idx] = t; |
132 |
} |
133 |
|
134 |
- /* allow for 1 optional suffix letter, must be following a number |
135 |
- * otherwise we eat stuff like -c, see bug #639978 */ |
136 |
- ptr = ret->PN + strlen(ret->PN); |
137 |
+ /* allow for 1 optional suffix letter, must be following a number */ |
138 |
+ ptr = ret->PV + strlen(ret->PV); |
139 |
if (ptr[-1] >= 'a' && ptr[-1] <= 'z' && |
140 |
- ptr - 2 > ret->PN && ptr[-2] >= '0' && ptr[-2] <= '9') |
141 |
+ ptr - 2 > ret->PV && ptr[-2] >= '0' && ptr[-2] <= '9') |
142 |
{ |
143 |
ret->letter = ptr[-1]; |
144 |
--ptr; |
145 |
} |
146 |
|
147 |
/* eat the trailing version number [-.0-9]+ */ |
148 |
- bool has_pv = false; |
149 |
- while (--ptr > ret->PN) |
150 |
+ while (--ptr > ret->PV) { |
151 |
if (*ptr == '-') { |
152 |
- has_pv = true; |
153 |
*ptr = '\0'; |
154 |
break; |
155 |
} else if (*ptr != '.' && !isdigit(*ptr)) |
156 |
break; |
157 |
- if (has_pv) { |
158 |
- ret->PV = ret->P + (ptr - ret->PN) + 1; |
159 |
- ptr = stpcpy(ret->PVR, ret->PV); |
160 |
- sprintf(ptr, "-r%i", ret->PR_int); |
161 |
- } else { |
162 |
- /* atom has no version */ |
163 |
- ret->PV = ret->PVR = NULL; |
164 |
- ret->letter = 0; |
165 |
} |
166 |
|
167 |
+ ptr = stpcpy(ret->PVR, ret->PV); |
168 |
+ sprintf(ptr, "-r%i", ret->PR_int); |
169 |
+ |
170 |
return ret; |
171 |
} |
172 |
|
173 |
|
174 |
diff --git a/tests/qatom/dotest b/tests/qatom/dotest |
175 |
index 4bb0460..a0e6a34 100755 |
176 |
--- a/tests/qatom/dotest |
177 |
+++ b/tests/qatom/dotest |
178 |
@@ -29,9 +29,9 @@ test l07 "cat pkg 123 >=" ">=cat/pkg-123" |
179 |
test l07 "cat pkg 123 = *" "=cat/pkg-123*" |
180 |
|
181 |
# Explicit format. |
182 |
-test f01 "cat" -F '%{CATEGORY}' "cat/pkg" |
183 |
-test f02 "<unset>" -F '%{CATEGORY}' "pkg" |
184 |
-test f03 "" -F '%[CATEGORY]' "pkg" |
185 |
+test f01 "cat" -F '%{CATEGORY}' "cat/pkg" |
186 |
+test f02 "<unset>" -F '%{CATEGORY}' "pkg" |
187 |
+test f03 "" -F '%[CATEGORY]' "pkg" |
188 |
test f04 "cat" -F '%{CATEGORY}' "cat/pkg-123-r4:5" |
189 |
test f05 "pkg-123" -F '%{P}' "cat/pkg-123-r4:5" |
190 |
test f06 "pkg" -F '%{PN}' "cat/pkg-123-r4:5" |
191 |
@@ -41,5 +41,12 @@ test f09 "pkg-123-r4" -F '%{PF}' "cat/pkg-123-r4:5" |
192 |
test f10 "r4" -F '%{PR}' "cat/pkg-123-r4:5" |
193 |
test f11 ":5" -F '%{SLOT}' "cat/pkg-123-r4:5" |
194 |
test f12 "pkg-c" -F '%{PN}' "cat/pkg-c" # bug #639978 |
195 |
+test f13 "mod_perl 1.5_p20180304 r5" \ |
196 |
+ -F '%{PN} %{PV} %{PR}' \ |
197 |
+ "dev-libs/mod_perl-1.5_p20180304-r5" |
198 |
+test f14 "foo-r1" -F '%{PN}' "foo-r1" # bug #526596 |
199 |
+test f15 "app-emacs diff-mode-" \ |
200 |
+ -F '%{CATEGORY} %{PN}' \ |
201 |
+ "app-emacs/diff-mode-" |
202 |
|
203 |
end |