-
Notifications
You must be signed in to change notification settings - Fork 277
JCI: don't load method instructions #3447
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
JCI: don't load method instructions #3447
Conversation
055a9a8
to
30aad53
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 30aad53).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91986750
{ | ||
REQUIRE(loaded_class.parsed_class.methods.size() == 1); | ||
|
||
const auto &method = *loaded_class.parsed_class.methods.begin(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Add a check here that the loaded class at least has the member variable x
I would also extend to check:
- accessibility of class
- inner class loaded
- accessibility of method
- annotations on method
- accessibility / annotations of fields
- type hierarchy
- a non constructor
@@ -78,6 +80,7 @@ class java_bytecode_parsert:public parsert | |||
}; | |||
|
|||
std::vector<bytecodet> bytecodes; | |||
bool skip_instructions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️
bool skip_instructions; | |
bool skip_instructions = false; |
if someone adds a new constructor and forgets to initialise this field we won't be left in UB
30aad53
to
37539f2
Compare
@thk123 I've added a test for a non-constructor -- the other attributes ought to have nothing to do with the dont-load-instructions flag, so I won't include those in this test |
That's why I thought a test would be good, to ensure doesn't accidentally not load too much - but approved anyway |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 37539f2).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/92286213
37539f2
to
75d8ee3
Compare
Ah, got you -- added such checks |
"java_bytecode_parse_class_without_instructions", | ||
"[core][java_bytecode][java_bytecode_parser]") | ||
{ | ||
null_message_handlert null_out; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a global null_message_handler
in the unit tests, no need for that one.
@@ -1215,7 +1218,7 @@ void java_bytecode_parsert::rmethod_attribute(methodt &method) | |||
|
|||
irep_idt attribute_name=pool_entry(attribute_name_index).s; | |||
|
|||
if(attribute_name=="Code") | |||
if(attribute_name=="Code" && !skip_instructions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-format will require adding space around ==
{ | ||
get_bytecodes(); | ||
if(!skip_instructions) | ||
get_bytecodes(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit surprised that we both need a class member and this branch here. But that may just be down to my limited understanding of the code here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method is badly named: this actually initialises a lookup table of possible bytecodes (only used within rbytecodes)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the if(!skip_instructions)
should be moved into this method as if(skip_instructions) return;
- you need to know what the method does in order to know whether you can skip it, and therefore to me it would seem better to place the condition with the implementation.
@@ -78,6 +80,7 @@ class java_bytecode_parsert:public parsert | |||
}; | |||
|
|||
std::vector<bytecodet> bytecodes; | |||
bool skip_instructions = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const ?
@@ -16,10 +16,28 @@ Author: Daniel Kroening, kroening@kroening.com | |||
|
|||
struct java_bytecode_parse_treet; | |||
|
|||
/// Attempt to parse a Java class from the given file. | |||
/// \param file: file to load from | |||
/// \param msg: gets log messages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ "gets" doesn't seem right here, maybe "handles"?
/// \param msg: gets log messages | ||
/// \param skip_instructions: if true, the loaded class's methods will all be | ||
/// empty. Saves time and memory for consumers that only want signature info. | ||
/// \return parse tree, or Empty on failure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ not sure "Empty" should be capitalized 🦅
/// \param msg: gets log messages | ||
/// \param skip_instructions: if true, the loaded class's methods will all be | ||
/// empty. Saves time and memory for consumers that only want signature info. | ||
/// \return parse tree, or Empty on failure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🦅
REQUIRE(loaded_class.is_inner_class); | ||
REQUIRE(loaded_class.outer_class == "Trivial"); | ||
|
||
const auto &fieldone = *loaded_class.fields.begin(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ field_one or field1
75d8ee3
to
e1388e1
Compare
|
||
java_bytecode_parse( | ||
const std::string &file, | ||
class message_handlert &msg, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class
keyword seems unnecessary (more occurrences)
This speeds loading 40000 classes up by around 3x.
e1388e1
to
8f7f8ae
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫
This PR failed Diffblue compatibility checks (cbmc commit: e1388e1).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/92313175
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 8f7f8ae).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/92316672
This speeds loading 40000 classes up by around 3x when the consumer isn't interested in the method bodies. (Use case: in the security product we found it useful to inspect class metadata using the same parser as will be used in jbmc, to ensure consistency between the two processes)