~ubuntu-branches/ubuntu/raring/reprepro/raring

« back to all changes in this revision

Viewing changes to checks.c

  • Committer: Bazaar Package Importer
  • Author(s): Bernhard R. Link
  • Date: 2011-05-05 16:34:23 UTC
  • mfrom: (21.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110505163423-x49kbdijyoubai4x
Tags: 4.6.0-1
* new release
- general cleanup
- new FilterSrcList
* increase Standards-Version, no changes needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
         * anyway). */
46
46
        uchar c = *character;
47
47
 
48
 
        if( (c & (uchar)0xC2 /*11000010*/) == (uchar)0xC0 /*11000000*/ ) {
 
48
        if ((c & (uchar)0xC2 /*11000010*/) == (uchar)0xC0 /*11000000*/) {
49
49
                uchar nextc = *(character+1);
50
50
 
51
 
                if( (nextc & (uchar)0xC0 /*11000000*/ ) != (uchar)0x80 /*10000000*/ )
 
51
                if ((nextc & (uchar)0xC0 /*11000000*/)
 
52
                                != (uchar)0x80 /*10000000*/)
52
53
                        return false;
53
54
 
54
 
                if( (c & (uchar)0x3E /* 00111110 */ ) == (uchar)0 )
55
 
                        return true;
56
 
                if( c == (uchar)0xE0 /*11100000*/ &&
57
 
                    (nextc & (uchar)0x20 /*00100000*/ ) == (uchar)0)
58
 
                        return true;
59
 
                if( c == (uchar)0xF0 /*11110000*/ &&
60
 
                    (nextc & (uchar)0x30 /*00110000*/ ) == (uchar)0)
61
 
                        return true;
62
 
                if( c == (uchar)0xF8 /*11111000*/ &&
63
 
                    (nextc & (uchar)0x38 /*00111000*/ ) == (uchar)0)
64
 
                        return true;
65
 
                if( c == (uchar)0xFC /*11111100*/ &&
66
 
                    (nextc & (uchar)0x3C /*00111100*/ ) == (uchar)0)
 
55
                if ((c & (uchar)0x3E /* 00111110 */) == (uchar)0)
 
56
                        return true;
 
57
                if (c == (uchar)0xE0 /*11100000*/ &&
 
58
                    (nextc & (uchar)0x20 /*00100000*/) == (uchar)0)
 
59
                        return true;
 
60
                if (c == (uchar)0xF0 /*11110000*/ &&
 
61
                    (nextc & (uchar)0x30 /*00110000*/) == (uchar)0)
 
62
                        return true;
 
63
                if (c == (uchar)0xF8 /*11111000*/ &&
 
64
                    (nextc & (uchar)0x38 /*00111000*/) == (uchar)0)
 
65
                        return true;
 
66
                if (c == (uchar)0xFC /*11111100*/ &&
 
67
                    (nextc & (uchar)0x3C /*00111100*/) == (uchar)0)
67
68
                        return true;
68
69
        }
69
70
        return false;
70
71
}
71
72
 
72
 
#define REJECTLOWCHARS(s,str,descr) \
73
 
        if( (uchar)*s < (uchar)' ' ) { \
 
73
#define REJECTLOWCHARS(s, str, descr) \
 
74
        if ((uchar)*s < (uchar)' ') { \
74
75
                fprintf(stderr, \
75
76
                        "Character 0x%02hhx not allowed within %s '%s'!\n", \
76
 
                        *s,descr,str); \
 
77
                        *s, descr, str); \
77
78
                return RET_ERROR; \
78
79
        }
79
80
 
80
 
#define REJECTCHARIF(c,s,str,descr) \
81
 
        if( c ) { \
 
81
#define REJECTCHARIF(c, s, str, descr) \
 
82
        if (c) { \
82
83
                fprintf(stderr, \
83
84
                        "Character '%c' not allowed within %s '%s'!\n", \
84
 
                        *s,descr,string); \
 
85
                        *s, descr, string); \
85
86
                return RET_ERROR; \
86
87
        }
87
88
 
91
92
        const char *s;
92
93
        bool firstcharacter = true;
93
94
 
94
 
        if( string[0] == '\0' ) {
 
95
        if (string[0] == '\0') {
95
96
                /* This is not really ignoreable, as this will lead
96
97
                 * to paths not normalized, so all checks go wrong */
97
 
                fprintf(stderr,"Source name is not allowed to be emtpy!\n");
 
98
                fprintf(stderr, "Source name is not allowed to be emtpy!\n");
98
99
                return RET_ERROR;
99
100
        }
100
 
        if( string[0] == '.' ) {
 
101
        if (string[0] == '.') {
101
102
                /* A dot is not only hard to see, it would cause the directory
102
103
                 * to become /./.bla, which is quite dangerous. */
103
 
                fprintf(stderr,"Source names are not allowed to start with a dot!\n");
 
104
                fprintf(stderr,
 
105
"Source names are not allowed to start with a dot!\n");
104
106
                return RET_ERROR;
105
107
        }
106
108
        s = string;
107
 
        while( *s != '\0' ) {
108
 
                if( (*s > 'z' || *s < 'a' ) &&
109
 
                    (*s > '9' || *s < '0' ) &&
 
109
        while (*s != '\0') {
 
110
                if ((*s > 'z' || *s < 'a') &&
 
111
                    (*s > '9' || *s < '0') &&
110
112
                    (firstcharacter ||
111
 
                     ( *s != '+' && *s != '-' && *s != '.'))) {
112
 
                        REJECTLOWCHARS(s,string,"sourcename");
113
 
                        REJECTCHARIF( *s == '/', s,string, "sourcename");
114
 
                        if( overlongUTF8(s) ) {
 
113
                     (*s != '+' && *s != '-' && *s != '.'))) {
 
114
                        REJECTLOWCHARS(s, string, "sourcename");
 
115
                        REJECTCHARIF (*s == '/', s, string, "sourcename");
 
116
                        if (overlongUTF8(s)) {
115
117
                                fprintf(stderr,
116
118
"This could contain an overlong UTF8 sequence, rejecting source name '%s'!\n",
117
119
                                        string);
118
120
                                return RET_ERROR;
119
121
                        }
120
 
                        if( !IGNORING(
121
 
"Not rejecting", "To ignore this", forbiddenchar,
122
 
"Character 0x%02hhx not allowed in sourcename: '%s'!\n", *s, string) ) {
 
122
                        if (!IGNORING_(forbiddenchar,
 
123
"Character 0x%02hhx not allowed in sourcename: '%s'!\n", *s, string)) {
123
124
                                return RET_ERROR;
124
125
                        }
125
 
                        if( ISSET(*s,0x80) ) {
126
 
                                if( !IGNORING(
127
 
"Not rejecting", "To ignore this", 8bit,
128
 
"8bit character in source name: '%s'!\n",       string) ) {
 
126
                        if (ISSET(*s, 0x80)) {
 
127
                                if (!IGNORING_(8bit,
 
128
"8bit character in source name: '%s'!\n", string)) {
129
129
                                        return RET_ERROR;
130
130
                                }
131
131
                        }
140
140
retvalue properfilename(const char *string) {
141
141
        const char *s;
142
142
 
143
 
        if( string[0] == '\0' ) {
144
 
                fprintf(stderr,"Error: empty filename!\n");
 
143
        if (string[0] == '\0') {
 
144
                fprintf(stderr, "Error: empty filename!\n");
145
145
                return RET_ERROR;
146
146
        }
147
 
        if( (string[0] == '.' && string[1] == '\0') ||
148
 
                (string[0] == '.' && string[1] == '.' && string[2] == '\0') ) {
 
147
        if ((string[0] == '.' && string[1] == '\0') ||
 
148
                (string[0] == '.' && string[1] == '.' && string[2] == '\0')) {
149
149
                fprintf(stderr, "File name not allowed: '%s'!\n", string);
150
150
                return RET_ERROR;
151
151
        }
152
 
        for( s = string ; *s != '\0'  ; s++ ) {
153
 
                REJECTLOWCHARS(s,string,"filename");
154
 
                REJECTCHARIF( *s == '/' ,s,string,"filename");
155
 
                if( ISSET(*s,0x80) ) {
156
 
                        if( overlongUTF8(s) ) {
 
152
        for (s = string ; *s != '\0'  ; s++) {
 
153
                REJECTLOWCHARS(s, string, "filename");
 
154
                REJECTCHARIF (*s == '/' , s, string, "filename");
 
155
                if (ISSET(*s, 0x80)) {
 
156
                        if (overlongUTF8(s)) {
157
157
                                fprintf(stderr,
158
158
"This could contain an overlong UTF8 sequence, rejecting file name '%s'!\n",
159
159
                                                string);
160
160
                                return RET_ERROR;
161
161
                        }
162
 
                        if( !IGNORING(
163
 
"Not rejecting", "To ignore this", 8bit,
164
 
"8bit character in file name: '%s'!\n",         string)) {
 
162
                        if (!IGNORING_(8bit,
 
163
"8bit character in file name: '%s'!\n", string)) {
165
164
                                return RET_ERROR;
166
165
                        }
167
166
                }
173
172
        va_list ap;
174
173
        static char *data = NULL;
175
174
 
176
 
        if( data != NULL )
 
175
        if (data != NULL)
177
176
                free(data);
178
177
        va_start(ap, format);
179
178
        data = vmprintf(format, ap);
180
179
        va_end(ap);
181
 
        if( data == NULL )
 
180
        if (data == NULL)
182
181
                return "Out of memory";
183
182
        return data;
184
183
}
187
186
const char *checkfordirectoryandidentifier(const char *string) {
188
187
        const char *s;
189
188
 
190
 
        assert( string != NULL && string[0] != '\0' );
 
189
        assert (string != NULL && string[0] != '\0');
191
190
 
192
 
        if( (string[0] == '.' && (string[1] == '\0'||string[1]=='/')) )
 
191
        if ((string[0] == '.' && (string[1] == '\0'||string[1]=='/')))
193
192
                return "'.' is not allowed as directory part";
194
 
        if( (string[0] == '.' && string[1] == '.' &&
195
 
                        (string[2] == '\0'||string[2] =='/')) )
 
193
        if ((string[0] == '.' && string[1] == '.'
 
194
                                && (string[2] == '\0'||string[2] =='/')))
196
195
                return "'..' is not allowed as directory part";
197
 
        for( s = string; *s != '\0'; s++ ) {
198
 
                if( *s == '|' )
 
196
        for (s = string; *s != '\0'; s++) {
 
197
                if (*s == '|')
199
198
                        return "'|' is not allowed";
200
 
                if( (uchar)*s < (uchar)' ' )
 
199
                if ((uchar)*s < (uchar)' ')
201
200
                        return formaterror("Character 0x%02hhx not allowed", *s);
202
 
                if( *s == '/' && s[1] == '.' && (s[2] == '\0' || s[2] == '/') )
 
201
                if (*s == '/' && s[1] == '.' && (s[2] == '\0' || s[2] == '/'))
203
202
                        return "'.' is not allowed as directory part";
204
 
                if( *s == '/' && s[1] == '.' && s[2] == '.' &&
205
 
                                        (s[3] == '\0' || s[3] =='/'))
 
203
                if (*s == '/' && s[1] == '.' && s[2] == '.'
 
204
                                && (s[3] == '\0' || s[3] =='/'))
206
205
                        return "'..' is not allowed as directory part";
207
 
                if( *s == '/' && s[1] == '/' )
 
206
                if (*s == '/' && s[1] == '/')
208
207
                        return "\"//\" is not allowed";
209
 
                if( ISSET(*s,0x80) ) {
210
 
                        if( overlongUTF8(s) )
211
 
                                return "Contains overlong UTF-8 sequence if treated as UTF-8";
212
 
                        if( !IGNORABLE(8bit) )
213
 
                                return "Contains 8bit character (use --ignore=8bit to ignore)";
 
208
                if (ISSET(*s, 0x80)) {
 
209
                        if (overlongUTF8(s))
 
210
                                return
 
211
"Contains overlong UTF-8 sequence if treated as UTF-8";
 
212
                        if (!IGNORABLE(8bit))
 
213
                                return
 
214
"Contains 8bit character (use --ignore=8bit to ignore)";
214
215
                }
215
216
        }
216
217
        return NULL;
220
221
const char *checkforidentifierpart(const char *string) {
221
222
        const char *s;
222
223
 
223
 
        assert( string != NULL && string[0] != '\0' );
 
224
        assert (string != NULL && string[0] != '\0');
224
225
 
225
 
        for( s = string; *s != '\0' ; s++ ) {
226
 
                if( *s == '|' )
 
226
        for (s = string; *s != '\0' ; s++) {
 
227
                if (*s == '|')
227
228
                        return "'|' is not allowed";
228
 
                if( *s == '/' )
 
229
                if (*s == '/')
229
230
                        return "'/' is not allowed";
230
 
                if( (uchar)*s < (uchar)' ' )
 
231
                if ((uchar)*s < (uchar)' ')
231
232
                        return formaterror("Character 0x%02hhx not allowed", *s);
232
 
                if( ISSET(*s,0x80) ) {
233
 
                        if( overlongUTF8(s) )
234
 
                                return "Contains overlong UTF-8 sequence if treated as UTF-8";
235
 
                        if( !IGNORABLE(8bit) )
236
 
                                return "Contains 8bit character (use --ignore=8bit to ignore)";
 
233
                if (ISSET(*s, 0x80)) {
 
234
                        if (overlongUTF8(s))
 
235
                                return
 
236
"Contains overlong UTF-8 sequence if treated as UTF-8";
 
237
                        if (!IGNORABLE(8bit))
 
238
                                return
 
239
"Contains 8bit character (use --ignore=8bit to ignore)";
237
240
                }
238
241
        }
239
242
        return NULL;
242
245
retvalue properfilenamepart(const char *string) {
243
246
        const char *s;
244
247
 
245
 
        for( s = string ; *s != '\0' ; s++ ) {
246
 
                REJECTLOWCHARS(s,string,"filenamepart");
247
 
                REJECTCHARIF( *s == '/' ,s,string,"filenamepart");
248
 
                if( ISSET(*s,0x80) ) {
249
 
                        if( overlongUTF8(s) ) {
 
248
        for (s = string ; *s != '\0' ; s++) {
 
249
                REJECTLOWCHARS(s, string, "filenamepart");
 
250
                REJECTCHARIF (*s == '/' , s, string, "filenamepart");
 
251
                if (ISSET(*s, 0x80)) {
 
252
                        if (overlongUTF8(s)) {
250
253
                                fprintf(stderr,
251
254
"This could contain an overlong UTF8 sequence, rejecting part of file name '%s'!\n",
252
255
                                        string);
253
256
                                return RET_ERROR;
254
257
                        }
255
 
                        if( !IGNORING(
256
 
"Not rejecting", "To ignore this", 8bit, "8bit character in part of file name: '%s'!\n",
 
258
                        if (!IGNORING_(8bit,
 
259
"8bit character in part of file name: '%s'!\n",
257
260
                                        string))
258
261
                                return RET_ERROR;
259
262
                }
267
270
        bool first = true;
268
271
        bool yetonlydigits = true;
269
272
 
270
 
        if( string[0] == '\0' && !IGNORING(
271
 
"Ignoring","To ignore this",emptyfilenamepart,"A version string is empty!\n") ) {
 
273
        if (string[0] == '\0' && !IGNORING(emptyfilenamepart,
 
274
"A version string is empty!\n")) {
272
275
                return RET_ERROR;
273
276
        }
274
 
        if( ( *s < '0' || *s > '9' ) &&
275
 
            (( *s >= 'a' && *s <= 'z') || (*s >='A' && *s <= 'Z'))) {
 
277
        if ((*s < '0' || *s > '9') &&
 
278
            ((*s >= 'a' && *s <= 'z') || (*s >='A' && *s <= 'Z'))) {
276
279
                /* As there are official packages violating the rule
277
280
                 * of policy 5.6.11 to start with a digit, disabling
278
281
                 * this test, and only omitting a warning. */
279
 
                if( verbose >= 0 )
280
 
                        fprintf(stderr,"Warning: Package version '%s' does not start with a digit, violating 'should'-directive in policy 5.6.11\n",string);
 
282
                if (verbose >= 0)
 
283
                        fprintf(stderr,
 
284
"Warning: Package version '%s' does not start with a digit, violating 'should'-directive in policy 5.6.11\n",
 
285
                                string);
281
286
        }
282
 
        for( ; *s != '\0' ; s++,first=false ) {
283
 
                if( (*s <= '9' || *s >= '0' ) ) {
 
287
        for (; *s != '\0' ; s++, first=false) {
 
288
                if ((*s <= '9' || *s >= '0')) {
284
289
                        continue;
285
290
                }
286
 
                if( !first && yetonlydigits && *s == ':' ) {
 
291
                if (!first && yetonlydigits && *s == ':') {
287
292
                        hadepoch = true;
288
293
                        continue;
289
294
                }
290
295
                yetonlydigits = false;
291
 
                if( (*s >= 'A' && *s <= 'Z' ) ||
292
 
                           (*s >= 'a' || *s <= 'z' )) {
 
296
                if ((*s >= 'A' && *s <= 'Z') ||
 
297
                           (*s >= 'a' || *s <= 'z')) {
293
298
                        yetonlydigits = false;
294
299
                        continue;
295
300
                }
296
 
                if( first || (*s != '+'  && *s != '-' &&
297
 
                              *s != '.'  && *s != '~' &&
298
 
                              (!hadepoch || *s != ':' ))) {
299
 
                        REJECTLOWCHARS(s,string,"version");
300
 
                        REJECTCHARIF( *s == '/' ,s,string,"version");
301
 
                        if( overlongUTF8(s) ) {
 
301
                if (first || (*s != '+'  && *s != '-'
 
302
                                        && *s != '.'  && *s != '~'
 
303
                                        && (!hadepoch || *s != ':'))) {
 
304
                        REJECTLOWCHARS(s, string, "version");
 
305
                        REJECTCHARIF (*s == '/' , s, string, "version");
 
306
                        if (overlongUTF8(s)) {
302
307
                                fprintf(stderr,
303
308
"This could contain an overlong UTF8 sequence, rejecting version '%s'!\n",
304
309
                                                string);
305
310
                                return RET_ERROR;
306
311
                        }
307
 
                        if( !IGNORING(
308
 
"Not rejecting", "To ignore this", forbiddenchar,
309
 
"Character '%c' not allowed in version: '%s'!\n",       *s, string) )
 
312
                        if (!IGNORING_(forbiddenchar,
 
313
"Character '%c' not allowed in version: '%s'!\n", *s, string))
310
314
                                return RET_ERROR;
311
 
                        if( ISSET(*s,0x80) ) {
312
 
                                if( !IGNORING(
313
 
"Not rejecting", "To ignore this", 8bit,
314
 
"8bit character in version: '%s'!\n",   string) )
 
315
                        if (ISSET(*s, 0x80)) {
 
316
                                if (!IGNORING_(8bit,
 
317
"8bit character in version: '%s'!\n", string))
315
318
                                        return RET_ERROR;
316
319
                        }
317
320
                }
322
325
retvalue properfilenames(const struct strlist *names) {
323
326
        int i;
324
327
 
325
 
        for( i = 0 ; i < names->count ; i ++ ) {
 
328
        for (i = 0 ; i < names->count ; i ++) {
326
329
                retvalue r = properfilename(names->values[i]);
327
 
                assert( r != RET_NOTHING );
328
 
                if( RET_WAS_ERROR(r) )
 
330
                assert (r != RET_NOTHING);
 
331
                if (RET_WAS_ERROR(r))
329
332
                        return r;
330
333
        }
331
334
        return RET_OK;
338
341
        /* To be able to avoid multiple warnings,
339
342
         * this should always be a subset of propersourcename */
340
343
 
341
 
        if( string[0] == '\0' ) {
 
344
        if (string[0] == '\0') {
342
345
                /* This is not really ignoreable, as this is a primary
343
346
                 * key for our database */
344
 
                fprintf(stderr,"Package name is not allowed to be emtpy!\n");
 
347
                fprintf(stderr, "Package name is not allowed to be emtpy!\n");
345
348
                return RET_ERROR;
346
349
        }
347
350
        s = string;
348
 
        while( *s != '\0' ) {
 
351
        while (*s != '\0') {
349
352
                /* DAK also allowed upper case letters last I looked, policy
350
353
                 * does not, so they are not allowed without --ignore=forbiddenchar */
351
354
                // perhaps some extra ignore-rule for upper case?
352
 
                if( (*s > 'z' || *s < 'a' ) &&
353
 
                    (*s > '9' || *s < '0' ) &&
354
 
                    ( firstcharacter ||
355
 
                      (*s != '+' && *s != '-' && *s != '.'))) {
356
 
                        REJECTLOWCHARS(s,string,"package name");
357
 
                        REJECTCHARIF( *s == '/' ,s,string,"package name");
358
 
                        if( overlongUTF8(s) ) {
 
355
                if ((*s > 'z' || *s < 'a') &&
 
356
                    (*s > '9' || *s < '0') &&
 
357
                    (firstcharacter
 
358
                     || (*s != '+' && *s != '-' && *s != '.'))) {
 
359
                        REJECTLOWCHARS(s, string, "package name");
 
360
                        REJECTCHARIF (*s == '/' , s, string, "package name");
 
361
                        if (overlongUTF8(s)) {
359
362
                                fprintf(stderr,
360
363
"This could contain an overlong UTF8 sequence, rejecting package name '%s'!\n",
361
364
                                                string);
362
365
                                return RET_ERROR;
363
366
                        }
364
 
                        if( !IGNORING(
365
 
"Not rejecting", "To ignore this", forbiddenchar,
366
 
"Character 0x%02hhx not allowed in package name: '%s'!\n", *s, string) ) {
 
367
                        if (!IGNORING(forbiddenchar,
 
368
"Character 0x%02hhx not allowed in package name: '%s'!\n", *s, string)) {
367
369
                                return RET_ERROR;
368
370
                        }
369
 
                        if( ISSET(*s,0x80) ) {
370
 
                                if( !IGNORING(
371
 
"Not rejecting","To ignore this",8bit,"8bit character in package name: '%s'!\n",string) ) {
 
371
                        if (ISSET(*s, 0x80)) {
 
372
                                if (!IGNORING_(8bit,
 
373
"8bit character in package name: '%s'!\n", string)) {
372
374
                                        return RET_ERROR;
373
375
                                }
374
376
                        }