From d3d0c0d8f99ab9947c9b4ac20a90dcb9e48fb2b1 Mon Sep 17 00:00:00 2001 From: Thierry Vignaud Date: Wed, 5 Sep 2012 17:23:59 +0000 Subject: (parse_synthesis__XS) enable to read xz & bzip2 compressed synthesis (backported from trunk) Including "Do not try to parse current pointer when the line is invalid or empgty" commit which fixes a "Conditional jump or move depends on uninitialised value" during empty synthesis parsing --- NEWS | 1 + URPM.xs | 34 +++++++++++++++++++++++----------- t/synthesis.t | 18 ++++++++++++++---- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index 2b4af68..393f3d8 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ - don't read/write after the string when the synthesis is slightly malformed +- enable to read xz & bzip2 compressed synthesis Version 3.38.1.1 - 29 February 2012 diff --git a/URPM.xs b/URPM.xs index 091cd10..0d70ac1 100644 --- a/URPM.xs +++ b/URPM.xs @@ -20,7 +20,6 @@ #include #include #include -#include #include #undef Fflush @@ -3312,12 +3311,13 @@ Urpm_parse_synthesis__XS(urpm, filename, ...) if (depslist != NULL) { char buff[65536]; - char *p, *eol; + char *p, *eol, *t; int buff_len; struct s_Package pkg; - gzFile f; + FD_t f = NULL; int start_id = 1 + av_len(depslist); SV *callback = NULL; + rpmCompressedMagic compressed = COMPRESSED_OTHER; if (items > 2) { int i; @@ -3332,12 +3332,25 @@ Urpm_parse_synthesis__XS(urpm, filename, ...) } PUTBACK; - if ((f = gzopen(filename, "rb")) != NULL) { + int rc = rpmFileIsCompressed(filename, &compressed); + + switch (compressed) { + case COMPRESSED_BZIP2: t = "r.bzip2"; break; + case COMPRESSED_LZMA: + case COMPRESSED_XZ: + t = "r.xz"; break; + case COMPRESSED_OTHER: + default: + t = "r.gzip"; break; + } + f = Fopen(filename, "r.fdio"); + + if (!rc && (f = Fdopen(f, t)) != NULL && !Ferror(f)) { memset(&pkg, 0, sizeof(struct s_Package)); buff[sizeof(buff)-1] = 0; p = buff; int ok = 1; - while ((buff_len = gzread(f, p, sizeof(buff)-1-(p-buff))) >= 0 && + while ((buff_len = Fread(p, sizeof(buff)-1-(p-buff), 1, f)) >= 0 && (buff_len += p-buff)) { buff[buff_len] = 0; p = buff; @@ -3353,17 +3366,16 @@ Urpm_parse_synthesis__XS(urpm, filename, ...) ok = 0; break; } - if (gzeof(f)) { - if (!parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) ok = 0; - break; - } else { /* move the remaining non-complete-line at beginning */ memmove(buff, p, buff_len-(p-buff)); /* point to the end of the non-complete-line */ p = &buff[buff_len-(p-buff)]; - } } - if (gzclose(f) != 0) ok = 0; + // EOF: + if (ok && buff_len > 0 + && !parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) + ok = 0; + if (Fclose(f) != 0) ok = 0; SPAGAIN; if (ok) { XPUSHs(sv_2mortal(newSViv(start_id))); diff --git a/t/synthesis.t b/t/synthesis.t index 6729b3b..8961e2a 100644 --- a/t/synthesis.t +++ b/t/synthesis.t @@ -2,29 +2,39 @@ use strict ; use warnings ; -use Test::More tests => 94; +use Test::More tests => 95; use URPM; chdir 't' if -d 't'; my $file1 = 'synthesis.sample.cz'; +my $file2 = 'synthesis.sample-xz.cz'; -open my $f, "| gzip -9 >$file1"; -print $f <<'EOF'; +my $s = <<'EOF'; @provides@glibc-devel == 6:2.2.4-25mdk @requires@/sbin/install-info@glibc == 2.2.4@kernel-headers@kernel-headers >= 2.2.1@/bin/sh@/bin/sh@/bin/sh@rpmlib(PayloadFilesHavePrefix) <= 4.0-1@rpmlib(CompressedFileNames) <= 3.0.4-1 @conflicts@texinfo < 3.11@gcc < 2.96-0.50mdk @obsoletes@libc-debug@libc-headers@libc-devel@linuxthreads-devel@glibc-debug @info@glibc-devel-2.2.4-25mdk.i586@6@45692097@Development/C EOF +open my $f, "| gzip -9 >$file1"; +print $f $s; +close $f; +open my $f, "| xz -9 >$file2"; +print $f $s; +$s =~ s/-devel//g; +print $f $s; close $f; -END { unlink $file1 } +END { unlink $file1, $file2 } my $a = new URPM; ok($a); my ($first, $end); +($first, $end) = URPM->new->parse_synthesis($file2); +ok($first == 0 && $end == 1, 'parse XZ synthesis'); + ($first, $end) = URPM->new->parse_synthesis('empty_synthesis.cz'); is("$first $end", "0 -1", 'parse empty synthesis'); -- cgit v1.2.1