Re: Real basic...
by ikegami (Patriarch) on Feb 04, 2009 at 14:13 UTC
|
I don't have time to address this in depth, but I can at least explain the problem.
In the first pass of the outer loop, the inner loop reads SUMMARY to the end. Thus, in subsequent passes of the outer loop, the inner doesn't get executed since the file pointer is already at the end of the file.
You'll need to seek to the start of the file before the inner loop (poor choice), or load the summary file into memory before entering the outer loop (better choice).
By the way, there's never any reason to do foreach (<$fh>). Use while (<$fh>) instead.
Update: Assuming each line has a unique id,
#!/usr/bin/perl -w
use strict;
use Text::CSV_XS qw( );
@ARGV == 1
or die("usage: $0 id\n");
my ($query_id) = @ARGV;
my $csv = Text::CSV_XS->new();
my $query_cve_id;
{
my $map_qfn = 'vuln_cve_map.csv';
open(my $map_fh, '<', $map_qfn)
or die("Can't open mapping file \"$map_qfn\": $!\n");
while (my $row = $csv->getline($map_fh)) {
my ($id, $cve_id) = @$row;
if ($id == $query) {
$query_cve_id = $cve_id};
last;
}
}
}
{
my $summary_qfn = 'CVE_summary.csv';
open(my $summary_fh, '<', $sumamry_qfn)
or die("Can't open CVE Summary file \"$summary_qfn\": $!\n");
while (my $row = $csv->getline($summary_fh)) {
my ($cve_id, $summary) = @$row;
if ($cve_id == $query_cve_id) {
print("[$cve_id] $summary\n");
last;
}
}
}
| [reply] [d/l] [select] |
|
|
Thanks.
The identifiers are indeed unique, so this should work perfectly. The first section of code works fine, returning the cve_id.
In the second section the array isn't getting populated
Any ideas?
| [reply] |
|
|
| [reply] |
|
|
|
|
|
Re: Real basic...
by moritz (Cardinal) on Feb 04, 2009 at 14:19 UTC
|
Your current approach doesn't work, because you iterate over all lines of CVE_summary.csv in the inner loop, and when you enter that loop again, the file handle is already exhausted.
So the solution is to read one file, and store its content into a data structure (an array or a hash), and then open the second file, and for each line of the second file you look into the previously created data structure for the information you want.
If you want a more concrete example, give us some example data (a few lines from each file would be enough). | [reply] [d/l] |
|
|
That makes sense, thanks.
The first file contains just a number and a corresponding NVD/CVE identifier.
The code is part of a cgi script that get the id number (the 4,9, 10) as it's input.
I want to find the corresponding CVE identifier and use it to search the next file.
scott$ head vuln_cve_map.csv
4,CVE-2005-4727
5,CVE-2005-4727
9,CVE-2005-4727
10,CVE-2005-4727
18,CVE-2006-5917
19,CVE-2006-5917
23,CVE-2006-5917
24,CVE-2006-5917
32,CVE-2006-1913
33,CVE-2006-1913
The second file looks like this:
Ping:~/RiskView scott$ head CVE_summary.csv
"CVE-1999-0095","The debug command in Sendmail is enabled
"CVE-1999-0082","CWD ~root command in ftpd allows root access."
"CVE-1999-1471","Buffer overflow in passwd in BSD based operating systems 4.3 and earlier allows local users to gain root privileges by specifying a long shell or GECOS field."
"CVE-1999-1122","Vulnerability in restore in SunOS 4.0.3 and earlier allows local users to gain privileges."
"CVE-1999-1467","Vulnerability in rcp on SunOS 4.0.x allows remote attackers from trusted hosts to execute arbitrary commands as root
"CVE-1999-1506","Vulnerability in SMI Sendmail 4.0 and earlier
"CVE-1999-0084","Certain NFS servers allow users to use mknod to gain privileges by creating a writable kmem device and setting the UID to 0."
"CVE-2000-0388","Buffer overflow in FreeBSD libmytinfo library allows local users to execute commands via a long TERMCAP environmental variable."
"CVE-1999-0209","The SunView (SunTools) selection_svc facility allows remote users to read files."
"CVE-1999-1198","BuildDisk program on NeXT systems before 2.0 does not prompt users for the root password
So that's the goal, match the input to the first field in the first file, and output the summary field in the second.
Thanks, guys...
| [reply] |
|
|
The following should get you started. Could be the regexes need a bit of tweaking. Note the use of subs that nicely separate the task into distinct problems and allow easy code reuse.
Your post is nearly unreadable. Dont use </br>. Use <br> or <br/>! I wonder where that meme comes from.
my $desc = get_bug_description(4, 'first.csv', 'second.csv');
sub get_bug_description
{
my ($id, $key_file, $desc_file) = @_;
my $cve = get_bug_cve($id, $key_file);
open my $file, '<', $desc_file;
while (<$file>)
{
return $1
if /"$cve","([^"]+)/;
}
close $file;
return;
}
sub get_bug_cve
{
my ($id, $key_file) = @_;
open my $file, '<', $key_file;
while (<$file>)
{
return $1
if /$id,(.+)/;
}
close $file;
return;
}
holli
When you're up to your ass in alligators, it's difficult to remember that your original purpose was to drain the swamp.\
| [reply] [d/l] [select] |