Skip to content

Commit a901ed9

Browse files
committed
Merge pull request #37 from bruceravel/memory
Address memory leaks in libxdifile
2 parents 6d2c754 + 78e99b9 commit a901ed9

File tree

16 files changed

+512
-198
lines changed

16 files changed

+512
-198
lines changed

baddata/BadFiles.txt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ bad_07.xdi file read(2) Y No Column labels -
1414
bad_08.xdi file read(2) Y Too few Column labels
1515
bad_09.xdi file read(2) Y Too many Column labels
1616
bad_10.xdi file read(2) Y Column indices not continuous
17-
bad_11.xdi error msg Y Unsupported comment character
17+
bad_11.xdi file read(3) Y Unsupported comment character
1818
bad_12.xdi file read(1) Y angle given without mono.d_spacing
1919
bad_13.xdi error msg Y inconsistent number of columns in data table -- too few
2020
bad_14.xdi error msg Y inconsistent number of columns in data table -- too many
@@ -26,17 +26,18 @@ bad_19.xdi error msg Y Header 'Family.Key: Value' -- no ':'
2626
bad_20.xdi error msg Y Header 'Family.Key: Value' -- two ':'
2727
bad_21.xdi error msg Y Header 'Family.Key: Value' -- no '.'
2828
bad_22.xdi error msg Y Header 'Family.Key: Value' -- two '.'
29-
bad_23.xdi file read(3) Y Header 'Family.Key: Value' -- key starts with number
29+
bad_23.xdi file read(4) Y Header 'Family.Key: Value' -- key starts with number
3030
bad_24.xdi error msg Y Header 'Family.Key: Value' -- Family starts with number
31-
bad_25.xdi file read(4) Y No extra version given
32-
bad_26.xdi file read(5) Y No user comment
33-
bad_27.xdi file read(5) Y Line of '////', but no user comment
31+
bad_25.xdi file read(5) Y No extra version given
32+
bad_26.xdi file read(6) Y No user comment
33+
bad_27.xdi file read(6) Y Line of '////', but no user comment
3434
bad_28.xdi error msg Y incorrectly format date-time
3535
bad_29.xdi error msg Y date-time has invalid range (month > 12)
3636

3737
Notes:
3838
1. files read, return value > 0, indicating Warning
3939
2. extra column labels ignored, unspecified column labels set to 'colN' (N=1...)
40-
3. keys are allowed to start with a number...
41-
4. extra version is left as empty string ''
42-
5. user comment is left as empty string ''
40+
3. lines with unrecognized comment characters ignored
41+
4. keys are allowed to start with a number...
42+
5. extra version is left as empty string ''
43+
6. user comment is left as empty string ''

c/Makefile.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ includedir = @includedir@
2020
# you may have to alter these settings
2121
#---------------------------------
2222

23-
CCOPTS = -fPIC
23+
CCOPTS = -fPIC -g
2424
## CCOPTS = -arch i386 -arch x86_64
2525

2626
# you shouldn't have to alter anything below this line

c/strutil.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ int readlines(char *filename, char **textlines) {
3333
as char *text[MAX] */
3434

3535
FILE *finp;
36-
char *thisline ;
37-
char *text, *c;
36+
char *thisline;
37+
char *text;
3838
long file_length, index, i, ilen;
3939
int is_newline;
40+
char *orig_text, *orig_thisline;
4041

4142
finp = fopen(filename, "r");
4243
if (finp == NULL) {
@@ -50,6 +51,9 @@ int readlines(char *filename, char **textlines) {
5051

5152
text = calloc(file_length + 1, sizeof(char));
5253
thisline = calloc(MAX_LINE_LENGTH, sizeof(char));
54+
/* need to save a pointers to the beginning of the original strings so they can be freed at the end of this function */
55+
orig_text = text;
56+
orig_thisline = thisline;
5357

5458
if (text == NULL ) {
5559
printf("\nnot enough memory to read file.\n");
@@ -83,6 +87,11 @@ int readlines(char *filename, char **textlines) {
8387
return -EFBIG;
8488
}
8589
}
90+
/* free strings */
91+
text = orig_text;
92+
thisline = orig_thisline;
93+
free(text);
94+
free(thisline);
8695
return ilen;
8796
}
8897

c/strutil.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#define CR "\n"
22
#define CRLF "\n\r"
33

4+
#define MAX_WORD_LENGTH 8192 /* Max length of an interpretable word */
45
#define MAX_LINE_LENGTH 8192 /* Max chars in a line */
56
#define MAX_LINES 16384 /* Max number of lines */
67
#define MAX_WORDS 128

c/test_valgrind.pl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/perl
2+
3+
use strict;
4+
use warnings;
5+
use Test::More tests => 90;
6+
7+
## good data
8+
foreach my $file (qw(co_metal_rt.xdi
9+
cu_metal_10K.xdi
10+
cu_metal_rt.xdi
11+
fe2o3_rt.xdi
12+
fe3c_rt.xdi
13+
fe_metal_rt.xdi
14+
fen_rt.xdi
15+
feo_rt1.xdi
16+
ni_metal_rt.xdi
17+
nonxafs_1d.xdi
18+
nonxafs_2d.xdi
19+
pt_metal_rt.xdi
20+
se_na2so4_rt.xdi
21+
se_znse_rt.xdi
22+
zn_znse_rt.xdi
23+
)) {
24+
my $command = "valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ./xdi_reader ../data/$file 2>&1";
25+
my $x = `$command`;
26+
ok(($x =~ m{All heap blocks were freed}), $file);
27+
ok((not $?), "$file return value is 0");
28+
};
29+
30+
31+
## see baddata/BadFile.txt for explanations of return values
32+
my %return = ('00' => 0, '01' => 1, '02' => 0, '03' => 0, '04' => 0, '05' => 0,
33+
'06' => 0, '07' => 0, '08' => 0, '09' => 0, '10' => 0, '11' => 0,
34+
'12' => 0, '13' => 1, '14' => 1, '15' => 1, '16' => 1, '17' => 1,
35+
'18' => 1, '19' => 1, '20' => 1, '21' => 1, '22' => 1, '23' => 0,
36+
'24' => 1, '25' => 0, '26' => 0, '27' => 0, '28' => 1, '29' => 1, );
37+
38+
## bad data
39+
foreach my $i (0 .. 29) {
40+
my $n = sprintf("%2.2d", $i);
41+
my $command = "valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ./xdi_reader ../baddata/bad_$n.xdi 2>&1";
42+
my $x = `$command`;
43+
ok(($x =~ m{All heap blocks were freed}), "bad_$n.xdi");
44+
ok((not ($? xor $return{$n})), "bad_$n.xdi return value is $?");
45+
};
46+
47+
48+

c/xdi_reader.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ int main(int argc, char **argv) {
3636
if (ret < 0) {
3737
printf("Error reading XDI file '%s':\n %s\t(error code = %ld)\n",
3838
argv[1], XDI_errorstring(ret), ret);
39+
XDI_cleanup(xdifile, ret);
3940
return 1;
4041
}
4142

@@ -82,6 +83,7 @@ int main(int argc, char **argv) {
8283
}
8384
printf("\n");
8485
}
85-
free(xdifile);
86+
free(tdat);
87+
XDI_cleanup(xdifile, 0);
8688
return 0;
8789
}

0 commit comments

Comments
 (0)