Skip to content

WAR load support #608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added regression/cbmc-java/war-file1/sample.war
Binary file not shown.
9 changes: 9 additions & 0 deletions regression/cbmc-java/war-file1/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE
sample.war
--function mypackage.Hello.doGet --cover location
^EXIT=0$
^SIGNAL=0$
\*\* 25 of 26 covered
--
--
war file source https://tomcat.apache.org/tomcat-6.0-doc/appdev/sample/
1 change: 1 addition & 0 deletions regression/cbmc-java/war-file1/url.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://tomcat.apache.org/tomcat-6.0-doc/appdev/sample/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I very much appreciate that comment - but you might even place it in the test.desc file (so as not to create a non-standard file): you can place comments after another --, see test.pl --help

3 changes: 2 additions & 1 deletion src/goto-cc/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,8 @@ bool compilet::parse_source(const std::string &file_name)
return true;

if((has_suffix(file_name, ".class") ||
has_suffix(file_name, ".jar")) &&
has_suffix(file_name, ".jar") ||
has_suffix(file_name, ".war")) &&
final())
return true;

Expand Down
7 changes: 7 additions & 0 deletions src/java_bytecode/jar_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Author: Daniel Kroening, [email protected]

#include <json/json_parser.h>
#include <util/suffix.h>
#include <util/suffix.h>
#include <util/invariant.h>

void jar_filet::open(
Expand Down Expand Up @@ -53,6 +54,12 @@ void jar_filet::open(
#endif
INVARIANT(file_name.size()==filename_len-1, "no \\0 found in file name");

// remove WAR class prefix
// cf. https://en.wikipedia.org/wiki/WAR_(file_format)
const std::string war_class_prefix("WEB-INF/classes/");
if(has_prefix(file_name, war_class_prefix))
file_name=file_name.substr(war_class_prefix.length());

// non-class files are loaded in any case
bool add_file=!has_suffix(file_name, ".class");
// load .class file only if they match regex / are in match set
Expand Down
68 changes: 45 additions & 23 deletions src/java_bytecode/java_bytecode_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,7 @@ void java_bytecode_languaget::get_language_options(const cmdlinet &cmd)
java_cp_include_files=cmd.get_value("java-cp-include-files");
// load file list from JSON file
if(java_cp_include_files[0]=='@')
{
jsont json_cp_config;
if(parse_json(
java_cp_include_files.substr(1),
get_message_handler(),
json_cp_config))
throw "cannot read JSON input configuration for JAR loading";

if(!json_cp_config.is_object())
throw "the JSON file has a wrong format";
jsont include_files=json_cp_config["jar"];
if(!include_files.is_array())
throw "the JSON file has a wrong format";

// add jars from JSON config file to classpath
for(const jsont &file_entry : include_files.array)
{
assert(file_entry.is_string() && has_suffix(file_entry.value, ".jar"));
config.java.classpath.push_back(file_entry.value);
}
}
load_from_archive_files(java_cp_include_files.substr(1));
}
else
java_cp_include_files=".*";
Expand All @@ -98,7 +78,7 @@ void java_bytecode_languaget::get_language_options(const cmdlinet &cmd)

std::set<std::string> java_bytecode_languaget::extensions() const
{
return { "class", "jar" };
return { "class", "jar", "war" };
}

void java_bytecode_languaget::modules_provided(std::set<std::string> &modules)
Expand Down Expand Up @@ -130,7 +110,7 @@ bool java_bytecode_languaget::parse(
// override main_class
main_class=java_class_loadert::file_to_class_name(path);
}
else if(has_suffix(path, ".jar"))
else if(has_suffix(path, ".jar") || has_suffix(path, ".war"))
{
// build an object to potentially limit which classes are loaded
java_class_loader_limitt class_loader_limit(
Expand Down Expand Up @@ -462,3 +442,45 @@ bool java_bytecode_languaget::to_expr(
java_bytecode_languaget::~java_bytecode_languaget()
{
}

void java_bytecode_languaget::load_from_archive_files(
const std::string &json_config)
{
jsont json_cp_config;
if(parse_json(
json_config,
get_message_handler(),
json_cp_config))
throw "cannot read JSON input configuration for JAR/WAR loading";

if(!json_cp_config.is_object())
throw "the JSON file has a wrong format";
jsont include_jar_files=json_cp_config["jar"];
if(!include_jar_files.is_null())
{
if(!include_jar_files.is_array())
throw "the JSON file has a wrong format";

// add jars from JSON config file to classpath
for(const jsont &file_entry : include_jar_files.array)
{
assert(file_entry.is_string() &&
has_suffix(file_entry.value, ".jar"));
config.java.classpath.push_back(file_entry.value);
}
}
jsont include_war_files=json_cp_config["war"];
if(!include_war_files.is_null())
{
if(!include_war_files.is_array())
throw "the JSON file has a wrong format";

// add wars from JSON config file to classpath
for(const jsont &file_entry : include_war_files.array)
{
assert(file_entry.is_string() &&
has_suffix(file_entry.value, ".war"));
config.java.classpath.push_back(file_entry.value);
}
}
}
1 change: 1 addition & 0 deletions src/java_bytecode/java_bytecode_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class java_bytecode_languaget:public languaget
protected:
bool do_ci_lazy_method_conversion(symbol_tablet &, lazy_methodst &);
const select_pointer_typet &get_pointer_type_selector() const;
void load_from_archive_files(const std::string &);

irep_idt main_class;
std::vector<irep_idt> main_jar_classes;
Expand Down
4 changes: 2 additions & 2 deletions src/java_bytecode/java_class_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ java_bytecode_parse_treet &java_class_loadert::get_parse_tree(
for(const auto &cp : config.java.classpath)
{
// in a JAR?
if(has_suffix(cp, ".jar"))
if(has_suffix(cp, ".jar") || has_suffix(cp, ".war"))
{
read_jar_file(class_loader_limit, cp);

Expand All @@ -119,7 +119,7 @@ java_bytecode_parse_treet &java_class_loadert::get_parse_tree(

if(jm_it!=jm.entries.end())
{
debug() << "Getting class `" << class_name << "' from JAR "
debug() << "Getting class `" << class_name << "' from {J,W}AR "
<< cp << eom;

std::string data=jar_pool(class_loader_limit, cp)
Expand Down