cprover
jar_file.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "jar_file.h"
10 
11 #include <cstring>
12 #include <cassert>
13 #include <unordered_set>
14 
15 #include <json/json_parser.h>
16 #include <util/suffix.h>
17 
19  java_class_loader_limitt &class_loader_limit,
20  const std::string &filename)
21 {
22  if(!mz_ok)
23  {
24  memset(&zip, 0, sizeof(zip));
25  mz_bool mz_open=mz_zip_reader_init_file(&zip, filename.c_str(), 0);
26  mz_ok=mz_open==MZ_TRUE;
27  }
28 
29  if(mz_ok)
30  {
31  std::size_t number_of_files=
33 
34  for(std::size_t i=0; i<number_of_files; i++)
35  {
36  mz_uint filename_length=mz_zip_reader_get_filename(&zip, i, nullptr, 0);
37  char *filename_char=new char[filename_length+1];
38  mz_uint filename_len=
39  mz_zip_reader_get_filename(&zip, i, filename_char, filename_length);
40  assert(filename_length==filename_len);
41  std::string file_name(filename_char);
42 
43  // non-class files are loaded in any case
44  bool add_file=!has_suffix(file_name, ".class");
45  // load .class file only if they match regex / are in match set
46  add_file|=class_loader_limit.load_class_file(file_name);
47  if(add_file)
48  {
49  if(has_suffix(file_name, ".class"))
50  status() << "read class file " << file_name
51  << " from " << filename << eom;
52  filtered_jar[file_name]=i;
53  }
54  delete[] filename_char;
55  }
56  }
57 }
58 
60 {
61  if(mz_ok)
62  {
64  mz_ok=false;
65  }
66 }
67 
68 std::string jar_filet::get_entry(const irep_idt &name)
69 {
70  if(!mz_ok)
71  return std::string("");
72 
73  std::string dest;
74 
75  auto entry=filtered_jar.find(name);
76  assert(entry!=filtered_jar.end());
77 
78  size_t real_index=entry->second;
79  mz_zip_archive_file_stat file_stat;
80  memset(&file_stat, 0, sizeof(file_stat));
81  mz_bool stat_ok=mz_zip_reader_file_stat(&zip, real_index, &file_stat);
82  if(stat_ok!=MZ_TRUE)
83  return std::string();
84  std::vector<char> buffer;
85  size_t bufsize=file_stat.m_uncomp_size;
86  buffer.resize(bufsize);
87  mz_bool read_ok=
88  mz_zip_reader_extract_to_mem(&zip, real_index, buffer.data(), bufsize, 0);
89  if(read_ok!=MZ_TRUE)
90  return std::string();
91 
92  dest.insert(dest.end(), buffer.begin(), buffer.end());
93 
94  return dest;
95 }
96 
98 {
99  auto entry=filtered_jar.find("META-INF/MANIFEST.MF");
100  if(entry==filtered_jar.end())
101  return manifestt();
102 
103  std::string dest=get_entry(entry->first);
104  std::istringstream in(dest);
105 
106  manifestt manifest;
107 
108  std::string line;
109  while(std::getline(in, line))
110  {
111  std::size_t pos=line.find(':');
112  if(pos==std::string::npos)
113  continue;
114  std::string key=line.substr(0, pos);
115 
116  // skip spaces
117  pos++;
118  while(pos<line.size() && line[pos]==' ') pos++;
119 
120  std::string value=line.substr(pos, std::string::npos);
121 
122  // trim off \r
123  if(!value.empty() && *value.rbegin()=='\r')
124  value.resize(value.size()-1);
125 
126  // store
127  manifest[key]=value;
128  }
129 
130  return manifest;
131 }
void open(java_class_loader_limitt &, const std::string &)
Definition: jar_file.cpp:18
bool mz_bool
Definition: miniz.h:536
mstreamt & status()
Definition: message.h:238
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
Definition: miniz.cpp:7169
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
Definition: miniz.cpp:7114
literalt pos(literalt a)
Definition: literal.h:193
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
Definition: miniz.cpp:3803
filtered_jart filtered_jar
Definition: jar_file.h:40
static mstreamt & eom(mstreamt &m)
Definition: message.h:193
mz_zip_archive zip
Definition: jar_file.h:48
~jar_filet()
Definition: jar_file.cpp:59
manifestt get_manifest()
Definition: jar_file.cpp:97
std::string get_entry(const irep_idt &)
Definition: jar_file.cpp:68
unsigned int mz_uint
Definition: miniz.h:533
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags)
Definition: miniz.cpp:4398
mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
Definition: miniz.cpp:3724
mz_uint64 m_uncomp_size
Definition: miniz.h:991
JAR File Reading.
std::map< std::string, std::string > manifestt
Definition: jar_file.h:44
#define MZ_TRUE
Definition: miniz.h:539
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
Definition: miniz.cpp:7148
bool load_class_file(const irep_idt &class_file_name)
bool has_suffix(const std::string &s, const std::string &suffix)
Definition: suffix.h:15
bool mz_ok
Definition: jar_file.h:49