8
8
9
9
#include < cstring>
10
10
#include < cassert>
11
- #include < sstream >
11
+ #include < unordered_set >
12
12
13
+ #include < json/json_parser.h>
14
+ #include < util/suffix.h>
13
15
#include " jar_file.h"
14
-
15
16
/* ******************************************************************\
16
17
17
18
Function: jar_filet::open
@@ -24,7 +25,9 @@ Function: jar_filet::open
24
25
25
26
\*******************************************************************/
26
27
27
- void jar_filet::open (const std::string &filename)
28
+ void jar_filet::open (
29
+ std::string &java_cp_include_files,
30
+ const std::string &filename)
28
31
{
29
32
if (!mz_ok)
30
33
{
@@ -35,11 +38,37 @@ void jar_filet::open(const std::string &filename)
35
38
36
39
if (mz_ok)
37
40
{
41
+ // '@' signals file reading with list of class files to load
42
+ bool regex_match=java_cp_include_files[0 ]!=' @' ;
43
+ std::regex regex_matcher;
44
+ std::smatch string_matcher;
45
+ std::unordered_set<std::string> set_matcher;
46
+ jsont json_cp_config;
47
+ if (regex_match)
48
+ regex_matcher=std::regex (java_cp_include_files);
49
+ else
50
+ {
51
+ assert (java_cp_include_files.length ()>1 );
52
+ if (parse_json (
53
+ java_cp_include_files.substr (1 ),
54
+ get_message_handler (),
55
+ json_cp_config))
56
+ throw " cannot read JSON input configuration for JAR loading" ;
57
+ if (!json_cp_config.is_object ())
58
+ throw " the JSON file has a wrong format" ;
59
+ jsont include_files=json_cp_config[" classFiles" ];
60
+ if (!include_files.is_array ())
61
+ throw " the JSON file has a wrong format" ;
62
+ for (const jsont &file_entry : include_files.array )
63
+ {
64
+ assert (file_entry.is_string ());
65
+ set_matcher.insert (file_entry.value );
66
+ }
67
+ }
68
+
38
69
std::size_t number_of_files=
39
70
mz_zip_reader_get_num_files (&zip);
40
71
41
- index .reserve (number_of_files);
42
-
43
72
for (std::size_t i=0 ; i<number_of_files; i++)
44
73
{
45
74
mz_uint filename_length=mz_zip_reader_get_filename (&zip, i, nullptr , 0 );
@@ -48,8 +77,23 @@ void jar_filet::open(const std::string &filename)
48
77
mz_zip_reader_get_filename (&zip, i, filename_char, filename_length);
49
78
assert (filename_length==filename_len);
50
79
std::string file_name (filename_char);
80
+
81
+ // non-class files are loaded in any case
82
+ bool add_file=!has_suffix (file_name, " .class" );
83
+ // load .class file only if they match regex
84
+ if (regex_match)
85
+ add_file|=std::regex_match (file_name, string_matcher, regex_matcher);
86
+ // load .class file only if it is in the match set
87
+ else
88
+ add_file|=set_matcher.find (file_name)!=set_matcher.end ();
89
+ if (add_file)
90
+ {
91
+ if (has_suffix (file_name, " .class" ))
92
+ status () << " read class file " << file_name
93
+ << " from " << filename << eom;
94
+ filtered_jar[file_name]=i;
95
+ }
51
96
delete[] filename_char;
52
- index .push_back (file_name);
53
97
}
54
98
}
55
99
}
@@ -87,25 +131,27 @@ Function: jar_filet::get_entry
87
131
88
132
\*******************************************************************/
89
133
90
- std::string jar_filet::get_entry (std:: size_t i )
134
+ std::string jar_filet::get_entry (const irep_idt &name )
91
135
{
92
136
if (!mz_ok)
93
137
return std::string (" " );
94
138
95
- assert (i<index .size ());
96
-
97
139
std::string dest;
98
140
141
+ auto entry=filtered_jar.find (name);
142
+ assert (entry!=filtered_jar.end ());
143
+
144
+ size_t real_index=entry->second ;
99
145
mz_zip_archive_file_stat file_stat;
100
146
memset (&file_stat, 0 , sizeof (file_stat));
101
- mz_bool stat_ok=mz_zip_reader_file_stat (&zip, i , &file_stat);
147
+ mz_bool stat_ok=mz_zip_reader_file_stat (&zip, real_index , &file_stat);
102
148
if (stat_ok!=MZ_TRUE)
103
149
return std::string ();
104
150
std::vector<char > buffer;
105
151
size_t bufsize=file_stat.m_uncomp_size ;
106
152
buffer.resize (bufsize);
107
153
mz_bool read_ok=
108
- mz_zip_reader_extract_to_mem (&zip, i , buffer.data (), bufsize, 0 );
154
+ mz_zip_reader_extract_to_mem (&zip, real_index , buffer.data (), bufsize, 0 );
109
155
if (read_ok!=MZ_TRUE)
110
156
return std::string ();
111
157
@@ -128,24 +174,11 @@ Function: jar_filet::get_manifest
128
174
129
175
jar_filet::manifestt jar_filet::get_manifest ()
130
176
{
131
- std::size_t i=0 ;
132
- bool found=false ;
133
-
134
- for (const auto &e : index )
135
- {
136
- if (e==" META-INF/MANIFEST.MF" )
137
- {
138
- found=true ;
139
- break ;
140
- }
141
-
142
- i++;
143
- }
144
-
145
- if (!found)
177
+ auto entry=filtered_jar.find (" META-INF/MANIFEST.MF" );
178
+ if (entry==filtered_jar.end ())
146
179
return manifestt ();
147
180
148
- std::string dest=get_entry (i );
181
+ std::string dest=get_entry (entry-> first );
149
182
std::istringstream in (dest);
150
183
151
184
manifestt manifest;
0 commit comments