root/trunk/CONVERTALN/reader.cxx

Revision 7130, 3.1 KB (checked in by westram, 16 months ago)
  • fixed buffer overflow
Line 
1#include "reader.h"
2
3Reader::Reader(const char *inf)
4    : fp(fopen(inf, "rt")),
5      file(NULL), 
6      curr(NULL),
7      failure(false)
8{
9    reset();
10    try {
11        if (!fp) {
12            throw_errorf(1, "can't read input file '%s' (Reason: %s)", inf, strerror(errno));
13        }
14        file = new FileBuffer(inf, fp);
15        file->showFilenameInLineError(true);
16        read();
17    }
18    catch (Convaln_exception& exc) {
19        failure = true;
20        curr    = NULL;
21        throw;
22    }
23}
24
25Reader::~Reader() {
26    // if kicked by exception, decorate error-msg with current reader position
27    if (const Convaln_exception *exc = Convaln_exception::exception_thrown()) {
28        exc->replace_msg(file->lineError(exc->get_msg()).c_str());
29    }
30    else {
31        ca_assert(!curr); // reader did NOT read till EOF, why ?
32    }
33    delete file;
34}
35
36void Reader::read() {
37    if (!curr) {
38        failure = true; // read _beyond_ EOF
39    }
40    else {
41        ca_assert(!failure); // attempt to read after failure
42
43        string next_line;
44        if (!file->getLine(next_line)) {
45            curr = NULL;
46        }
47        else {
48            size_t len = next_line.length();
49
50            if (len >= (LINESIZE-1)) {
51                char lbuf[200];
52                memcpy(lbuf, next_line.c_str(), 200-4);
53                strcpy(lbuf+200-4, "...");
54                throw_errorf(148, "Line too long: '%s'", lbuf);
55            }
56            memcpy(linebuf, next_line.c_str(), len);
57            linebuf[len]     = '\n';
58            linebuf[len + 1] = 0;
59
60            curr = linebuf;
61        }
62    }
63}
64
65
66// --------------------------------------------------------------------------------
67
68FileWriter::FileWriter(const char *outname)
69    : ofp(NULL),
70      filename(NULL),
71      written(0)
72{
73    ofp = fopen(outname, "wt");
74    if (!ofp) {
75        throw_errorf(2, "can't write output file '%s' (Reason: %s)", outname, strerror(errno));
76    }
77    filename = strdup(outname);
78}
79FileWriter::~FileWriter() {
80    bool fine      = ofp && !Convaln_exception::exception_thrown();
81    bool die_empty = fine && !written;
82
83    if (ofp) fclose(ofp);
84    if (!fine || die_empty) unlink(filename);
85    free(filename);
86
87    if (die_empty) {
88        throw_errorf(42, "No sequence has been written");
89    }
90
91    log_processed(written);
92}
93
94void Writer::throw_write_error() const {
95    throw_errorf(41, "Write error: %s(=%i) while writing %s",
96                 strerror(errno), errno, name());
97}
98void FileWriter::out(char ch) {
99    if (fputc(ch, ofp) == EOF) throw_write_error();
100}
101
102int FileWriter::outf(const char *format, ...) {
103    va_list parg;
104    va_start(parg, format);
105    int     printed = vfprintf(ofp, format, parg);
106    va_end(parg);
107    if (printed<0) throw_write_error();
108    return printed;
109}
110
111int Writer::outf(const char *format, ...) {
112    va_list parg;
113    va_start(parg, format);
114    char    buffer[LINESIZE];
115    int     printed = vsprintf(buffer, format, parg);
116    ca_assert(printed <= LINESIZE);
117    va_end(parg);
118
119    out(buffer);
120    return printed;
121}
122
123int Writer::out(const char *text) {
124    int i = 0;
125    while (text[i]) {
126        out(text[i++]);
127    }
128    return i;
129}
Note: See TracBrowser for help on using the browser.