feat(library/module): include name of corrupted .olean file
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
d1c645977d
commit
0d97fff280
10 changed files with 63 additions and 49 deletions
|
@ -63,7 +63,7 @@ public:
|
||||||
case level_kind::Succ:
|
case level_kind::Succ:
|
||||||
return mk_succ(read());
|
return mk_succ(read());
|
||||||
}
|
}
|
||||||
throw_corrupted_file();
|
throw corrupted_stream_exception();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -247,7 +247,7 @@ public:
|
||||||
binder_info bi = read_binder_info(d);
|
binder_info bi = read_binder_info(d);
|
||||||
return mk_local(n, pp_n, read(), bi);
|
return mk_local(n, pp_n, read(), bi);
|
||||||
}}
|
}}
|
||||||
throw_corrupted_file(); // LCOV_EXCL_LINE
|
throw corrupted_stream_exception(); // LCOV_EXCL_LINE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -363,7 +363,7 @@ static register_macro_deserializer_fn
|
||||||
annotation_des_fn(get_annotation_opcode(),
|
annotation_des_fn(get_annotation_opcode(),
|
||||||
[](deserializer & d, unsigned num, expr const * args) {
|
[](deserializer & d, unsigned num, expr const * args) {
|
||||||
if (num != 1)
|
if (num != 1)
|
||||||
throw_corrupted_file();
|
throw corrupted_stream_exception();
|
||||||
name k;
|
name k;
|
||||||
d >> k;
|
d >> k;
|
||||||
return mk_annotation(k, args[0]);
|
return mk_annotation(k, args[0]);
|
||||||
|
|
|
@ -28,6 +28,10 @@ Author: Leonardo de Moura
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
corrupted_file_exception::corrupted_file_exception(std::string const & fname):
|
||||||
|
exception(sstream() << "failed to import '" << fname << "', file is corrupted") {
|
||||||
|
}
|
||||||
|
|
||||||
typedef std::pair<std::string, std::function<void(serializer &)>> writer;
|
typedef std::pair<std::string, std::function<void(serializer &)>> writer;
|
||||||
|
|
||||||
struct module_ext : public environment_extension {
|
struct module_ext : public environment_extension {
|
||||||
|
@ -229,47 +233,50 @@ struct import_modules_fn {
|
||||||
std::ifstream in(fname, std::ifstream::binary);
|
std::ifstream in(fname, std::ifstream::binary);
|
||||||
if (!in.good())
|
if (!in.good())
|
||||||
throw exception(sstream() << "failed to open file '" << fname << "'");
|
throw exception(sstream() << "failed to open file '" << fname << "'");
|
||||||
deserializer d1(in);
|
try {
|
||||||
std::string header;
|
deserializer d1(in);
|
||||||
d1 >> header;
|
std::string header;
|
||||||
if (header != g_olean_header)
|
d1 >> header;
|
||||||
throw exception(sstream() << "file '" << fname << "' does not seem to be a valid object Lean file, invalid header");
|
if (header != g_olean_header)
|
||||||
unsigned major, minor, claimed_hash;
|
throw exception(sstream() << "file '" << fname << "' does not seem to be a valid object Lean file, invalid header");
|
||||||
d1 >> major >> minor >> claimed_hash;
|
unsigned major, minor, claimed_hash;
|
||||||
// Enforce version?
|
d1 >> major >> minor >> claimed_hash;
|
||||||
|
// Enforce version?
|
||||||
|
|
||||||
unsigned num_imports = d1.read_unsigned();
|
unsigned num_imports = d1.read_unsigned();
|
||||||
buffer<module_name> imports;
|
buffer<module_name> imports;
|
||||||
for (unsigned i = 0; i < num_imports; i++)
|
for (unsigned i = 0; i < num_imports; i++)
|
||||||
imports.push_back(read_module_name(d1));
|
imports.push_back(read_module_name(d1));
|
||||||
|
|
||||||
unsigned code_size = d1.read_unsigned();
|
unsigned code_size = d1.read_unsigned();
|
||||||
std::vector<char> code(code_size);
|
std::vector<char> code(code_size);
|
||||||
for (unsigned i = 0; i < code_size; i++)
|
for (unsigned i = 0; i < code_size; i++)
|
||||||
code[i] = d1.read_char();
|
code[i] = d1.read_char();
|
||||||
|
|
||||||
unsigned computed_hash = hash(code_size, [&](unsigned i) { return code[i]; });
|
unsigned computed_hash = hash(code_size, [&](unsigned i) { return code[i]; });
|
||||||
if (claimed_hash != computed_hash)
|
if (claimed_hash != computed_hash)
|
||||||
throw exception(sstream() << "file '" << fname << "' has been corrupted, checksum mismatch");
|
throw exception(sstream() << "file '" << fname << "' has been corrupted, checksum mismatch");
|
||||||
|
|
||||||
module_info_ptr r = std::make_shared<module_info>();
|
module_info_ptr r = std::make_shared<module_info>();
|
||||||
r->m_fname = fname;
|
r->m_fname = fname;
|
||||||
r->m_counter = imports.size();
|
r->m_counter = imports.size();
|
||||||
r->m_module_idx = g_null_module_idx;
|
r->m_module_idx = g_null_module_idx;
|
||||||
m_import_counter++;
|
m_import_counter++;
|
||||||
std::string new_base = dirname(fname.c_str());
|
std::string new_base = dirname(fname.c_str());
|
||||||
std::swap(r->m_obj_code, code);
|
std::swap(r->m_obj_code, code);
|
||||||
for (auto i : imports) {
|
for (auto i : imports) {
|
||||||
auto d = load_module_file(new_base, i);
|
auto d = load_module_file(new_base, i);
|
||||||
d->m_dependents.push_back(r);
|
d->m_dependents.push_back(r);
|
||||||
|
}
|
||||||
|
m_module_info.insert(fname, r);
|
||||||
|
r->m_module_idx = m_next_module_idx++;
|
||||||
|
|
||||||
|
if (imports.empty())
|
||||||
|
add_import_module_task(r);
|
||||||
|
return r;
|
||||||
|
} catch (corrupted_stream_exception&) {
|
||||||
|
throw corrupted_file_exception(fname);
|
||||||
}
|
}
|
||||||
m_module_info.insert(fname, r);
|
|
||||||
r->m_module_idx = m_next_module_idx++;
|
|
||||||
|
|
||||||
if (imports.empty())
|
|
||||||
add_import_module_task(r);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_asynch_task(asynch_update_fn const & f) {
|
void add_asynch_task(asynch_update_fn const & f) {
|
||||||
|
|
|
@ -14,6 +14,11 @@ Author: Leonardo de Moura
|
||||||
#include "library/io_state.h"
|
#include "library/io_state.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
class corrupted_file_exception : public exception {
|
||||||
|
public:
|
||||||
|
corrupted_file_exception(std::string const & fname);
|
||||||
|
};
|
||||||
|
|
||||||
class module_name {
|
class module_name {
|
||||||
optional<unsigned> m_relative;
|
optional<unsigned> m_relative;
|
||||||
name m_name;
|
name m_name;
|
||||||
|
|
|
@ -293,7 +293,7 @@ static register_macro_deserializer_fn
|
||||||
resolve_macro_des_fn(g_resolve_opcode,
|
resolve_macro_des_fn(g_resolve_opcode,
|
||||||
[](deserializer &, unsigned num, expr const * args) {
|
[](deserializer &, unsigned num, expr const * args) {
|
||||||
if (num != 3)
|
if (num != 3)
|
||||||
throw_corrupted_file();
|
throw corrupted_stream_exception();
|
||||||
return mk_resolve_macro(args[0], args[1], args[2]);
|
return mk_resolve_macro(args[0], args[1], args[2]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ static register_macro_deserializer_fn
|
||||||
string_macro_des_fn(g_string_opcode,
|
string_macro_des_fn(g_string_opcode,
|
||||||
[](deserializer & d, unsigned num, expr const *) {
|
[](deserializer & d, unsigned num, expr const *) {
|
||||||
if (num != 0)
|
if (num != 0)
|
||||||
throw_corrupted_file();
|
throw corrupted_stream_exception();
|
||||||
std::string v = d.read_string();
|
std::string v = d.read_string();
|
||||||
return mk_string_macro(v);
|
return mk_string_macro(v);
|
||||||
});
|
});
|
||||||
|
|
|
@ -449,7 +449,7 @@ public:
|
||||||
name prefix = read();
|
name prefix = read();
|
||||||
return name(prefix, d.read_unsigned());
|
return name(prefix, d.read_unsigned());
|
||||||
}}
|
}}
|
||||||
throw_corrupted_file();
|
throw corrupted_stream_exception();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
} else {
|
} else {
|
||||||
unsigned i = d.read_unsigned();
|
unsigned i = d.read_unsigned();
|
||||||
if (i >= m_table.size())
|
if (i >= m_table.size())
|
||||||
throw_corrupted_file();
|
throw corrupted_stream_exception();
|
||||||
return m_table[i];
|
return m_table[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,8 @@ void serializer_core::write_int(int i) {
|
||||||
|
|
||||||
#define BIG_BUFFER 1024
|
#define BIG_BUFFER 1024
|
||||||
|
|
||||||
void throw_corrupted_file() {
|
corrupted_stream_exception::corrupted_stream_exception():
|
||||||
throw exception("corrupted binary file");
|
exception("corrupted binary file") {}
|
||||||
}
|
|
||||||
|
|
||||||
void serializer_core::write_double(double d) {
|
void serializer_core::write_double(double d) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
@ -49,7 +48,7 @@ std::string deserializer_core::read_string() {
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
break;
|
break;
|
||||||
if (c == EOF)
|
if (c == EOF)
|
||||||
throw_corrupted_file();
|
throw corrupted_stream_exception();
|
||||||
r += c;
|
r += c;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -66,7 +66,10 @@ inline deserializer & operator>>(deserializer & d, char & c) { c = d.read_char()
|
||||||
inline deserializer & operator>>(deserializer & d, bool & b) { b = d.read_bool(); return d; }
|
inline deserializer & operator>>(deserializer & d, bool & b) { b = d.read_bool(); return d; }
|
||||||
inline deserializer & operator>>(deserializer & d, double & b) { b = d.read_double(); return d; }
|
inline deserializer & operator>>(deserializer & d, double & b) { b = d.read_double(); return d; }
|
||||||
|
|
||||||
[[ noreturn ]] void throw_corrupted_file();
|
class corrupted_stream_exception : public exception {
|
||||||
|
public:
|
||||||
|
corrupted_stream_exception();
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
serializer & write_list(serializer & s, list<T> const & ls) {
|
serializer & write_list(serializer & s, list<T> const & ls) {
|
||||||
|
|
|
@ -357,7 +357,7 @@ public:
|
||||||
sexpr t = read();
|
sexpr t = read();
|
||||||
return sexpr(h, t);
|
return sexpr(h, t);
|
||||||
}}
|
}}
|
||||||
throw_corrupted_file();
|
throw corrupted_stream_exception();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue