static void load_zip(database &db, database::contents_id cid, const rpm_file_entry &file) { zip_file zip(&file.contents); std::vector<unsigned char> data; while (true) { try { if (!zip.next()) { break; } } catch (os_exception &e) { // FIXME: Use proper, zip_file-specific exception. // zip.name() is not necessarily valid at this point. db.add_java_error(cid, e.what(), ""); // Exit the loop because the file is likely corrupted significantly. break; } try { zip.data(data); } catch (os_exception &e) { // FIXME: Use proper, zip_file-specific exception. db.add_java_error(cid, e.what(), zip.name()); } if (java_class::has_signature(data)) { try { java_class jc(&data); db.add_java_class(cid, jc); } catch (java_class::exception &e) { db.add_java_error(cid, e.what(), zip.name()); } } } }
static void do_load_formats(const symboldb_options &opt, database &db, python_analyzer &pya, database::contents_id cid, const rpm_file_entry &file) { if (is_elf(file.contents)) { load_elf(opt, db, cid, file); } else if (looks_like_xml(file.contents.begin(), file.contents.end())) { load_xml(opt, db, cid, file); } else if (is_python(file.contents) || check_any(file.infos, is_python_path)) { load_python(opt, db, pya, cid, file); } else if (java_class::has_signature(file.contents)) { try { java_class jc(&file.contents); db.add_java_class(cid, jc); } catch (java_class::exception &e) { db.add_java_error(cid, e.what(), ""); } } if (zip_file::has_signature(file.contents)) { load_zip(db, cid, file); } }
static void test_java_class(database &db, pgconn_handle &conn) { std::vector<unsigned char> buffer; read_file("test/data/JavaClass.class", buffer); java_class jc(&buffer); db.txn_begin_no_sync(); db.add_java_class(/* fake */ database::contents_id(1), jc); db.txn_commit(); pgresult_handle res; res.execBinary (conn, "SELECT class_id, name, super_class, access_flags" " FROM symboldb.java_class" " JOIN symboldb.java_class_contents USING (class_id)" " WHERE contents_id = 1"); CHECK(res.ntuples() == 1); int classid, access_flags; std::string name, super_class; pg_response(res, 0, classid, name, super_class, access_flags); COMPARE_STRING(name, "com/redhat/symboldb/test/JavaClass"); COMPARE_STRING(super_class, "java/lang/Thread"); CHECK(access_flags == 1 + 16 + 32); pg_query_binary (conn, res, "SELECT name FROM symboldb.java_interface" " WHERE class_id = $1 ORDER BY name", classid); CHECK(res.ntuples() == 2); COMPARE_STRING(res.getvalue(0, 0), "java/lang/AutoCloseable"); COMPARE_STRING(res.getvalue(1, 0), "java/lang/Runnable"); pg_query (conn, res, "SELECT name FROM symboldb.java_class_reference" " WHERE class_id = $1 ORDER BY name", classid); { const char *expected[] = { "java/lang/AutoCloseable", "java/lang/Byte", "java/lang/Double", "java/lang/Exception", "java/lang/Float", "java/lang/Integer", "java/lang/Long", "java/lang/Runnable", "java/lang/Short", "java/lang/StackOverflowError", "java/lang/StringBuilder", "java/lang/Thread", NULL }; unsigned end = res.ntuples(); for (unsigned i = 0; i <= end; ++i) { if (i == end) { CHECK(expected[i] == NULL); } else if (expected[i] == NULL) { CHECK(false); break; } else { COMPARE_STRING(res.getvalue(i, 0), expected[i]); } } } res.exec (conn, "SELECT jc.name FROM symboldb.java_class jc" " JOIN symboldb.java_class_contents USING (class_id)" " JOIN symboldb.file f USING (contents_id)" " JOIN symboldb.package p USING (package_id)" " WHERE symboldb.nevra(p) = 'objectweb-asm4-0:4.1-2.fc18.noarch'" " AND f.name = '/usr/share/java/objectweb-asm4/asm.jar'" " ORDER BY jc.name"); { const char *expected[] = { "org/objectweb/asm/AnnotationVisitor", "org/objectweb/asm/AnnotationWriter", "org/objectweb/asm/Attribute", "org/objectweb/asm/ByteVector", "org/objectweb/asm/ClassReader", "org/objectweb/asm/ClassVisitor", "org/objectweb/asm/ClassWriter", "org/objectweb/asm/Context", "org/objectweb/asm/Edge", "org/objectweb/asm/FieldVisitor", "org/objectweb/asm/FieldWriter", "org/objectweb/asm/Frame", "org/objectweb/asm/Handle", "org/objectweb/asm/Handler", "org/objectweb/asm/Item", "org/objectweb/asm/Label", "org/objectweb/asm/MethodVisitor", "org/objectweb/asm/MethodWriter", "org/objectweb/asm/Opcodes", "org/objectweb/asm/Type", "org/objectweb/asm/signature/SignatureReader", "org/objectweb/asm/signature/SignatureVisitor", "org/objectweb/asm/signature/SignatureWriter", NULL }; unsigned end = res.ntuples(); CHECK(end > 0); for (unsigned i = 0; i <= end; ++i) { if (i == end) { CHECK(expected[i] == NULL); } else if (expected[i] == NULL) { CHECK(false); break; } else { COMPARE_STRING(res.getvalue(i, 0), expected[i]); } } } db.txn_begin(); db.add_java_error(database::contents_id(1), "error message", "/path"); db.add_java_error(database::contents_id(2), "error message", ""); db.txn_rollback(); }