source: rtems-tools/tester/covoar/Explanations.cc @ 0c4884a

Last change on this file since 0c4884a was e84b9f3, checked in by Alex White <alex.white@…>, on 04/05/21 at 16:40:03

covoar: Fix NULL check of wrong variable (CID #1399602)

CID 1399602: Dereference null return value in
Explanations::writeNotFound().

In Explanations::writeNotFound() there were two NULL checks of the
fileName variable where only one is needed. The second check has been
changed to a NULL check of notFoundFile to match the original intent.

Closes #4377

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*! @file Explanations.cc
2 *  @brief Explanations Implementation
3 *
4 *  This file contains the implementation of the functions
5 *  which provide a base level of functionality of a Explanations.
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <unistd.h>
12
13#include <rld.h>
14
15#include "Explanations.h"
16#include "app_common.h"
17
18namespace Coverage {
19
20  Explanations::Explanations()
21  {
22  }
23
24  Explanations::~Explanations()
25  {
26  }
27
28  void Explanations::load(
29    const char* const explanations
30  )
31  {
32    #define MAX_LINE_LENGTH 512
33    FILE       *explain;
34    char        *cStatus;
35    Explanation *e;
36    int          line = 1;
37
38    if (!explanations)
39      return;
40
41    explain = ::fopen( explanations, "r" );
42    if (!explain) {
43      std::ostringstream what;
44      what << "Unable to open " << explanations;
45      throw rld::error( what, "Explanations::load" );
46    }
47
48    while ( 1 ) {
49      e = new Explanation;
50      // Read the starting line of this explanation and
51      // skip blank lines between
52      do {
53        inputBuffer[0] = '\0';
54        cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, explain );
55        if (cStatus == NULL) {
56          goto done;
57        }
58        inputBuffer[ strlen(inputBuffer) - 1] = '\0';
59        line++;
60      } while ( inputBuffer[0] == '\0' );
61
62      // Have we already seen this one?
63      if (set.find( inputBuffer ) != set.end()) {
64        std::ostringstream what;
65        what << "line " << line
66             << "contains a duplicate explanation ("
67             << inputBuffer << ")";
68        throw rld::error( what, "Explanations::load" );
69      }
70
71      // Add the starting line and file
72      e->startingPoint = std::string(inputBuffer);
73      e->found = false;
74
75      // Get the classification
76      cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, explain );
77      if (cStatus == NULL) {
78        std::ostringstream what;
79        what << "line " << line
80             << "out of sync at the classification";
81        throw rld::error( what, "Explanations::load" );
82      }
83      inputBuffer[ strlen(inputBuffer) - 1] = '\0';
84      e->classification = inputBuffer;
85      line++;
86
87      // Get the explanation
88      while (1) {
89        cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, explain );
90        // fprintf( stderr, "%d - %s\n", line, inputBuffer );
91        if (cStatus == NULL) {
92          std::ostringstream what;
93          what << "line " << line
94               << "out of sync at the explanation";
95          throw rld::error( what, "Explanations::load" );
96        }
97        inputBuffer[ strlen(inputBuffer) - 1] = '\0';
98        line++;
99
100        const char delimiter[4] = "+++";
101        if (!strncmp( inputBuffer, delimiter, 3 )) {
102          break;
103        }
104        // XXX only taking last line.  Needs to be a vector
105        e->explanation.push_back( inputBuffer );
106      }
107
108      // Add this to the set of Explanations
109      set[ e->startingPoint ] = *e;
110    }
111done:
112    ;
113
114    #undef MAX_LINE_LENGTH
115  }
116
117  const Explanation *Explanations::lookupExplanation(
118    const std::string& start
119  )
120  {
121    if (set.find( start ) == set.end()) {
122      #if 0
123        std::cerr << "Warning: Unable to find explanation for "
124                  << start << std::endl;
125      #endif
126      return NULL;
127    }
128    set[ start ].found = true;
129    return &set[ start ];
130  }
131
132  void Explanations::writeNotFound(
133    const char* const fileName
134  )
135  {
136    FILE* notFoundFile;
137    bool  notFoundOccurred = false;
138
139    if (!fileName)
140      return;
141
142    notFoundFile = fopen( fileName, "w" );
143    if (notFoundFile == nullptr) {
144      std::ostringstream what;
145      what << "Unable to open " << fileName
146           << " out of sync at the explanation";
147      throw rld::error( what, "Explanations::writeNotFound" );
148    }
149
150    for (std::map<std::string, Explanation>::iterator itr = set.begin();
151         itr != set.end();
152         itr++) {
153      Explanation e = (*itr).second;
154      std::string key = (*itr).first;
155
156      if (!e.found) {
157        notFoundOccurred = true;
158        fprintf(
159          notFoundFile,
160          "%s\n",
161          e.startingPoint.c_str()
162        );
163      }
164    }
165    fclose( notFoundFile );
166
167    if (!notFoundOccurred) {
168      if (!unlink( fileName )) {
169        std::cerr << "Warning: Unable to unlink " << fileName
170                  << std::endl
171                  << std::endl;
172      }
173    }
174  }
175
176}
Note: See TracBrowser for help on using the repository browser.