Commit 15795bbb authored by Bernhard Link's avatar Bernhard Link

read Checksums-sha1 in .dsc files

parent 55002888
2008-03-09 Bernhard R. Link <brlink@debian.org>
* read Checksums-sha1 in .dsc files
2008-03-08 Bernhard R. Link <brlink@debian.org>
* When missing section or priority reprepro's includedsc and
changestool's add[dsc] look into the .diff and the .tar file.
......
......@@ -199,6 +199,66 @@ retvalue checksums_init(/*@out@*/struct checksums **checksums_p, char *hashes[cs
return RET_OK;
}
struct hashes {
struct hash_data {
const char *start; size_t len;
} hashes[cs_COUNT];
};
static retvalue checksums_initialize(/*@out@*/struct checksums **checksums_p, const struct hash_data *hashes) {
char *d;
struct checksums *n;
enum checksumtype type;
size_t len;
/* everything assumes yet that those are available */
if( hashes[cs_length].start == NULL || hashes[cs_md5sum].start == NULL ) {
*checksums_p = NULL;
return RET_ERROR;
}
len = hashes[cs_md5sum].len + 1 + hashes[cs_length].len;
for( type = cs_firstEXTENDED ; type < cs_hashCOUNT ; type++ ) {
if( hashes[type].start == NULL )
continue;
len += strlen(" :x:") + hashes[type].len;
}
n = malloc(sizeof(struct checksums) + len + 1);
if( FAILEDTOALLOC(n) )
return RET_ERROR_OOM;
memset(n, 0, sizeof(struct checksums));
d = n->representation;
for( type = cs_firstEXTENDED ; type < cs_hashCOUNT ; type++ ) {
if( hashes[type].start == NULL )
continue;
*(d++) = ':';
*(d++) = '1' + (char)(type - cs_firstEXTENDED);
*(d++) = ':';
n->parts[type].ofs = d - n->representation;
n->parts[type].len = (hashlen_t)hashes[type].len;
memcpy(d, hashes[type].start, hashes[type].len);
d += hashes[type].len;
*(d++) = ' ';
}
n->parts[cs_md5sum].ofs = d - n->representation;
n->parts[cs_md5sum].len = (hashlen_t)hashes[cs_md5sum].len;
memcpy(d, hashes[cs_md5sum].start, hashes[cs_md5sum].len);
d += hashes[cs_md5sum].len;
*(d++) = ' ';
n->parts[cs_length].ofs = d - n->representation;
n->parts[cs_length].len = (hashlen_t)hashes[cs_length].len;
memcpy(d, hashes[cs_length].start, hashes[cs_length].len);
d += hashes[cs_length].len;
*(d++) = '\0';
assert( (size_t)(d-n->representation) == len + 1 );
*checksums_p = n;
return RET_OK;
}
retvalue checksums_setall(/*@out@*/struct checksums **checksums_p, const char *combinedchecksum, size_t len, /*@null@*/const char *md5sum) {
size_t md5len;
retvalue r;
......@@ -548,51 +608,124 @@ retvalue checksumsarray_parse(struct checksumsarray *out, const struct strlist l
retvalue r;
int i;
struct checksumsarray a;
const struct strlist *lines = &l[cs_md5sum];
assert( lines != NULL );
struct strlist filenames;
size_t count = l[cs_md5sum].count;
struct hashes *parsed;
enum checksumtype cs;
/* +1 because the caller is likely include an additional file later */
r = strlist_init_n(lines->count+1, &a.names);
if( RET_WAS_ERROR(r) )
return r;
if( lines->count == 0 ) {
a.checksums = NULL;
checksumsarray_move(out, &a);
return RET_OK;
}
a.checksums = calloc(lines->count, sizeof(struct checksums *));
if( a.checksums == NULL ) {
strlist_done(&a.names);
parsed = calloc(count, sizeof(struct hashes));
if( FAILEDTOALLOC(parsed) ) {
return RET_ERROR_OOM;
}
for( i = 0 ; i < lines->count ; i++ ) {
char *filename;
r = calc_parsefileline(lines->values[i], &filename, &a.checksums[i]);
if( RET_WAS_ERROR(r) ) {
if( r != RET_ERROR_OOM )
fprintf(stderr, "Error was parsing %s\n",
strlist_init_n(count + 1, &filenames);
for( cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++ ) {
for( i = 0 ; i < l[cs].count ; i++ ) {
const char *line = l[cs].values[i];
const char *p = line,
*hash_start, *size_start, *filename;
size_t hash_len, size_len;
int fileofs;
while( *p == ' ' || *p == '\t' )
p++;
hash_start = p;
while( (*p >= '0' && *p <= '9') ||
(*p >= 'a' && *p <= 'f' ) )
p++;
hash_len = p - hash_start;
while( *p == ' ' || *p == '\t' )
p++;
while( *p == '0' && p[1] >= '0' && p[1] <= '9' )
p++;
size_start = p;
while( (*p >= '0' && *p <= '9') )
p++;
size_len = p - size_start;
while( *p == ' ' || *p == '\t' )
p++;
filename = p;
while( *p != '\0' && *p != ' ' && *p != '\t'
&& *p != '\r' && *p != '\n' )
p++;
if( unlikely( size_len == 0 || hash_len == 0
|| filename == p || *p != '\0' ) ) {
fprintf(stderr,
"Error parsing %s checksum line ' %s' within '%s'\n",
hash_name[cs], line,
filenametoshow);
strlist_done(&filenames);
free(parsed);
return RET_ERROR;
} else if( cs == cs_md5sum ) {
fileofs = filenames.count;
r = strlist_add_dup(&filenames, filename);
if( RET_WAS_ERROR(r) ) {
strlist_done(&filenames);
free(parsed);
return r;
}
parsed[fileofs].hashes[cs_md5sum].start = hash_start;
parsed[fileofs].hashes[cs_md5sum].len = hash_len;
parsed[fileofs].hashes[cs_length].start = size_start;
parsed[fileofs].hashes[cs_length].len = size_len;
} else {
struct hash_data *hashes;
// TODO: suboptimal, as we know where
// it likely is...
fileofs = strlist_ofs(&filenames, filename);
if( fileofs == -1 ) {
// TODO: future versions might add files
// her to the previous know ones instead,
// once md5sum hash may be empty...
fprintf(stderr,
"WARNING: %s checksum line ' %s' in '%s' has no corresponding Files line!\n",
hash_name[cs], line,
filenametoshow);
}
hashes = parsed[fileofs].hashes;
if( unlikely( hashes[cs_length].len
!= size_len
|| memcmp(hashes[cs_length].start,
size_start, size_len) != 0) ) {
fprintf(stderr,
"WARNING: %s checksum line ' %s' in '%s' contradicts 'Files' filesize!\n",
hash_name[cs], line,
filenametoshow);
if( i == 0 ) {
free(a.checksums);
a.checksums = NULL;
continue;
}
hashes[cs].start = hash_start;
hashes[cs].len = hash_len;
}
checksumsarray_done(&a);
return r;
}
r = strlist_add(&a.names, filename);
}
assert( count == filenames.count );
if( filenames.count == 0 ) {
strlist_done(&filenames);
strlist_init(&out->names);
out->checksums = NULL;
free(parsed);
return RET_OK;
}
a.checksums = calloc(filenames.count+1, sizeof(struct checksums *));
if( FAILEDTOALLOC(a.checksums) ) {
strlist_done(&filenames);
free(parsed);
return RET_ERROR_OOM;
}
strlist_move(&a.names, &filenames);
for( i = 0 ; i < a.names.count ; i++ ) {
r = checksums_initialize(a.checksums + i, parsed[i].hashes);
if( RET_WAS_ERROR(r) ) {
checksums_free(a.checksums[i]);
a.checksums[i] = NULL;
if( i == 0 ) {
free(a.checksums);
a.checksums = NULL;
}
free(parsed);
checksumsarray_done(&a);
return r;
}
}
checksumsarray_move(out, &a);
free(parsed);
return RET_OK;
}
......
......@@ -25,7 +25,6 @@
#include "error.h"
#include "mprintf.h"
#include "strlist.h"
#include "checksums.h"
#include "names.h"
extern int verbose;
......@@ -274,76 +273,6 @@ void names_overversion(const char **version, bool epochsuppressed) {
*version = n;
}
/* split a "<md5> <size> <filename>" into md5sum and filename */
retvalue calc_parsefileline(const char *fileline, char **filename, struct checksums **checksums) {
const char *md5,*md5end,*size,*sizeend,*fn,*fnend;
char *filen;
assert( fileline != NULL );
if( *fileline == '\0' )
return RET_NOTHING;
/* the md5sums begins after the (perhaps) heading spaces ... */
md5 = fileline;
while( xisspace(*md5) )
md5++;
if( *md5 == '\0' )
return RET_NOTHING;
/* ... and ends with the following spaces. */
md5end = md5;
while( (*md5end >= '0' && *md5end <= '9') ||
(*md5end >= 'a' && *md5end <= 'f' ) ||
(*md5end >= 'A' && *md5end <= 'F' ) )
md5end++;
if( *md5end == '\0' ) {
fprintf(stderr, "Expecting more data after md5sum!\n");
return RET_ERROR;
}
if( !xisspace(*md5end) ) {
fprintf(stderr, "Error in parsing md5hash or missing space afterwards!\n");
return RET_ERROR;
}
/* Then the size of the file is expected: */
size = md5end;
while( xisspace(*size) )
size++;
sizeend = size;
while( xisdigit(*sizeend) )
sizeend++;
if( !xisspace(*sizeend) ) {
fprintf(stderr,"Error in parsing size or missing space afterwards!\n");
return RET_ERROR;
}
/* Then the filename */
fn = sizeend;
while( xisspace(*fn) )
fn++;
fnend = fn;
while( *fnend != '\0' && !xisspace(*fnend) )
fnend++;
filen = strndup(fn,fnend-fn);
if( filen == NULL )
return RET_ERROR_OOM;
if( checksums != NULL ) {
retvalue r;
r = checksums_set(checksums, md5, md5end - md5,
size, sizeend - size);
if( RET_WAS_ERROR(r) ) {
free(filen);
return r;
}
}
if( filename != NULL )
*filename = filen;
else
free(filen);
return RET_OK;
}
char *calc_trackreferee(const char *codename,const char *sourcename,const char *sourceversion) {
return mprintf("%s %s %s",codename,sourcename,sourceversion);
}
......
......@@ -29,10 +29,6 @@ char *calc_downloadedlistpattern(const char *codename);
retvalue calc_dirconcats(const char *directory, const struct strlist *basefilenames,/*@out@*/struct strlist *files);
retvalue calc_inplacedirconcats(const char *directory, struct strlist *);
/* split a "<md5> <size> <filename>" into md5sum and filename */
struct checksums;
retvalue calc_parsefileline(const char *fileline, /*@out@*/char **filename, /*@out@*//*@null@*/struct checksums **);
/* move over a version number, if epochsuppresed is true, colons may happen even without epoch there */
void names_overversion(const char **version, bool epochsuppressed);
......
/* This file is part of "reprepro"
* Copyright (C) 2003,2004,2005,2006,2007 Bernhard R. Link
* Copyright (C) 2003,2004,2005,2006,2007,2008 Bernhard R. Link
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
......@@ -36,6 +36,51 @@
extern int verbose;
/* split a "<md5> <size> <filename>" into md5sum and filename */
static retvalue calc_parsefileline(const char *fileline, /*@out@*/char **filename) {
const char *p, *fn, *fnend;
char *filen;
assert( fileline != NULL );
if( *fileline == '\0' )
return RET_NOTHING;
/* the md5sums begins after the (perhaps) heading spaces ... */
p = fileline;
while( *p != '\0' && (*p == ' ' || *p == '\t') )
p++;
if( *p == '\0' )
return RET_NOTHING;
/* ... and ends with the following spaces. */
while( *p != '\0' && !(*p == ' ' || *p == '\t') )
p++;
if( *p == '\0' ) {
fprintf(stderr, "Expecting more data after md5sum!\n");
return RET_ERROR;
}
/* Then the size of the file is expected: */
while( (*p == ' ' || *p == '\t') )
p++;
while( *p !='\0' && !(*p == ' ' || *p == '\t') )
p++;
if( *p == '\0' ) {
fprintf(stderr, "Expecting more data after size!\n");
return RET_ERROR;
}
/* Then the filename */
fn = p;
while( (*fn == ' ' || *fn == '\t') )
fn++;
fnend = fn;
while( *fnend != '\0' && !(*fnend == ' ' || *fnend == '\t') )
fnend++;
filen = strndup(fn, fnend-fn);
if( FAILEDTOALLOC(filen) )
return RET_ERROR_OOM;
*filename = filen;
return RET_OK;
}
static retvalue getBasenames(const struct strlist *filelines,/*@out@*/struct strlist *basenames) {
int i;
......@@ -51,7 +96,7 @@ static retvalue getBasenames(const struct strlist *filelines,/*@out@*/struct str
char *basename;
const char *fileline=filelines->values[i];
r = calc_parsefileline(fileline,&basename,NULL);
r = calc_parsefileline(fileline, &basename);
if( RET_WAS_ERROR(r) )
break;
......
......@@ -1204,8 +1204,7 @@ testrun - -b . processincoming default 3<<EOF
returns 255
stderr
-v0=Data seems not to be signed trying to use directly...
*=Error in parsing md5hash or missing space afterwards!
*=Error was parsing dscfilename_fileversion~.dsc
*=Error parsing md5 checksum line ' md5sumindsc sizeindsc strangefile' within 'dscfilename_fileversion~.dsc'
-v0*=There have been errors!
EOF
sed -i "s/ md5sumindsc / dddddddddddddddddddddddddddddddd /" i/dscfilename_fileversion~.dsc
......@@ -1217,8 +1216,7 @@ testrun - -b . processincoming default 3<<EOF
returns 255
stderr
-v0=Data seems not to be signed trying to use directly...
*=Error in parsing size or missing space afterwards!
*=Error was parsing dscfilename_fileversion~.dsc
*=Error parsing md5 checksum line ' dddddddddddddddddddddddddddddddd sizeindsc strangefile' within 'dscfilename_fileversion~.dsc'
-v0*=There have been errors!
EOF
sed -i "s/ sizeindsc / 666 /" i/dscfilename_fileversion~.dsc
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment