Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/tools/fuzzing/libfuzzer/FuzzerIO.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- FuzzerIO.cpp - IO utils. -------------------------------------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
// IO functions.
10
//===----------------------------------------------------------------------===//
11
12
#include "FuzzerIO.h"
13
#include "FuzzerDefs.h"
14
#include "FuzzerExtFunctions.h"
15
#include <algorithm>
16
#include <cstdarg>
17
#include <fstream>
18
#include <iterator>
19
#include <sys/stat.h>
20
#include <sys/types.h>
21
22
namespace fuzzer {
23
24
static FILE *OutputFile = stderr;
25
26
6
long GetEpoch(const std::string &Path) {
27
6
  struct stat St;
28
6
  if (stat(Path.c_str(), &St))
29
0
    return 0;  // Can't stat, be conservative.
30
6
  return St.st_mtime;
31
6
}
32
33
16.2k
Unit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError) {
34
16.2k
  std::ifstream T(Path);
35
16.2k
  if (ExitOnError && !T) {
36
0
    Printf("No such directory: %s; exiting\n", Path.c_str());
37
0
    exit(1);
38
0
  }
39
16.2k
40
16.2k
  T.seekg(0, T.end);
41
16.2k
  auto EndPos = T.tellg();
42
16.2k
  if (EndPos < 0) return {};
43
16.2k
  size_t FileLen = EndPos;
44
16.2k
  if (MaxSize)
45
16.2k
    FileLen = std::min(FileLen, MaxSize);
46
16.2k
47
16.2k
  T.seekg(0, T.beg);
48
16.2k
  Unit Res(FileLen);
49
16.2k
  T.read(reinterpret_cast<char *>(Res.data()), FileLen);
50
16.2k
  return Res;
51
16.2k
}
52
53
0
std::string FileToString(const std::string &Path) {
54
0
  std::ifstream T(Path);
55
0
  return std::string((std::istreambuf_iterator<char>(T)),
56
0
                     std::istreambuf_iterator<char>());
57
0
}
58
59
0
void CopyFileToErr(const std::string &Path) {
60
0
  Printf("%s", FileToString(Path).c_str());
61
0
}
62
63
0
void WriteToFile(const Unit &U, const std::string &Path) {
64
0
  // Use raw C interface because this function may be called from a sig handler.
65
0
  FILE *Out = fopen(Path.c_str(), "w");
66
0
  if (!Out) return;
67
0
  fwrite(U.data(), sizeof(U[0]), U.size(), Out);
68
0
  fclose(Out);
69
0
}
70
71
void ReadDirToVectorOfUnits(const char *Path, Vector<Unit> *V,
72
0
                            long *Epoch, size_t MaxSize, bool ExitOnError) {
73
0
  long E = Epoch ? *Epoch : 0;
74
0
  Vector<std::string> Files;
75
0
  ListFilesInDirRecursive(Path, Epoch, &Files, /*TopDir*/true);
76
0
  size_t NumLoaded = 0;
77
0
  for (size_t i = 0; i < Files.size(); i++) {
78
0
    auto &X = Files[i];
79
0
    if (Epoch && GetEpoch(X) < E) continue;
80
0
    NumLoaded++;
81
0
    if ((NumLoaded & (NumLoaded - 1)) == 0 && NumLoaded >= 1024)
82
0
      Printf("Loaded %zd/%zd files from %s\n", NumLoaded, Files.size(), Path);
83
0
    auto S = FileToVector(X, MaxSize, ExitOnError);
84
0
    if (!S.empty())
85
0
      V->push_back(S);
86
0
  }
87
0
}
88
89
90
3
void GetSizedFilesFromDir(const std::string &Dir, Vector<SizedFile> *V) {
91
3
  Vector<std::string> Files;
92
3
  ListFilesInDirRecursive(Dir, 0, &Files, /*TopDir*/true);
93
3
  for (auto &File : Files)
94
16.2k
    if (size_t Size = FileSize(File))
95
16.2k
      V->push_back({File, Size});
96
3
}
97
98
std::string DirPlusFile(const std::string &DirPath,
99
16.2k
                        const std::string &FileName) {
100
16.2k
  return DirPath + GetSeparator() + FileName;
101
16.2k
}
102
103
3
void DupAndCloseStderr() {
104
3
  int OutputFd = DuplicateFile(2);
105
3
  if (OutputFd > 0) {
106
3
    FILE *NewOutputFile = OpenFile(OutputFd, "w");
107
3
    if (NewOutputFile) {
108
3
      OutputFile = NewOutputFile;
109
3
      if (EF->__sanitizer_set_report_fd)
110
3
        EF->__sanitizer_set_report_fd(
111
3
            reinterpret_cast<void *>(GetHandleFromFd(OutputFd)));
112
3
      DiscardOutput(2);
113
3
    }
114
3
  }
115
3
}
116
117
3
void CloseStdout() {
118
3
  DiscardOutput(1);
119
3
}
120
121
159
void Printf(const char *Fmt, ...) {
122
159
  va_list ap;
123
159
  va_start(ap, Fmt);
124
159
  vfprintf(OutputFile, Fmt, ap);
125
159
  va_end(ap);
126
159
  fflush(OutputFile);
127
159
}
128
129
}  // namespace fuzzer