prefix_ void senf::term::Terminfo::load(std::string const & term)
{
std::string filename (findTerminfo(term));
+ if (filename.empty()) throw InvalidTerminfoException();
std::ifstream is (filename.c_str());
- if (!is)
- throw InvalidTerminfoException();
+ if (!is) throw InvalidTerminfoException();
load(is);
}
std::string result;
for (std::string::const_iterator i (prgstr.begin()); i != prgstr.end(); ++i) {
- if (*i != '%') {
- result += *i;
- continue;
- }
- int width = 0, base = 0;
- switch (*++i) {
+ if (*i != '%') {
+ result += *i;
+ continue;
+ }
+ int width = 0, base = 0;
+ switch (*++i) {
case '%': result += *i; break;
case 'i': ++arg1; ++arg2; break;
- case 'c': result += char(stack.pop()); break;
+ case 'c': result += char(stack.pop()); break;
case 'x': base = 16; continue;
case '0': if (!base) base = 8;
case '1': case '2': case '3': case '4':
continue;
}
case '}': stack.push(width); break;
- // Binary operands are in infix (reversed) order
+ // Binary operands are in infix (reversed) order
case '+': stack.push(stack.pop() + stack.pop()); break;
case '-': stack.push(-stack.pop() + stack.pop()); break;
case '*': stack.push(stack.pop() * stack.pop()); break;
prefix_ std::string senf::term::Terminfo::findTerminfo(std::string const & name)
{
+ if (name.empty()) return "";
boost::filesystem::path subdir (name.substr(0,1)); subdir /= name;
- boost::filesystem::path tientry, tipath;
+ boost::filesystem::path tientry;
{
char const * tivar (::getenv("TERMINFO"));
if (tivar) {
- tipath = tivar;
- tientry = tipath / subdir;
+ tientry = boost::filesystem::path(tivar) / subdir;
if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
}
}
- tipath = "/etc/terminfo";
- tientry = tipath / subdir;
+ tientry = boost::filesystem::path("/etc/terminfo") / subdir;
if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
- tipath = "/lib/terminfo";
- tientry = tipath / subdir;
+ tientry = boost::filesystem::path("/lib/terminfo") / subdir;
if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
- tipath = "/usr/share/terminfo";
- tientry = tipath / subdir;
+ tientry = boost::filesystem::path("/usr/share/terminfo") / subdir;
if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
return "";
{
TerminfoHeader h;
is.read(static_cast<char*>(static_cast<void*>(&h)), sizeof(h));
- if (h.magic != TerminfoMagic)
- throw InvalidTerminfoException();
+ if (!is || h.magic != TerminfoMagic) throw InvalidTerminfoException();
name_.resize(h.namesSz);
is.read(&(name_[0]), name_.size());
+ if (!is) throw InvalidTerminfoException();
+ if (name_.size() & 1)
+ is.ignore(1u);
{
std::string::size_type n (name_.find('\0'));
if (n != std::string::npos)
for (BoolVec::iterator i (booleans_.begin()); i != booleans_.end(); ++i) {
char v;
is.read(&v, sizeof(v));
+ if (!is) throw InvalidTerminfoException();
*i = v;
}
if (booleans_.size() & 1)
for (NumberVec::iterator i (numbers_.begin()); i != numbers_.end(); ++i) {
number_t v;
is.read(static_cast<char*>(static_cast<void*>(&v)), sizeof(v));
+ if (!is) throw InvalidTerminfoException();
*i = v;
}
for (OffsetVec::iterator i (offsets.begin()); i != offsets.end(); ++i) {
number_t v;
is.read(static_cast<char*>(static_cast<void*>(&v)), sizeof(v));
+ if (!is) throw InvalidTerminfoException();
*i = v;
}
stringPool_.resize(h.stringPoolSz);
is.read(&(stringPool_[0]), stringPool_.size());
+ if (!is) throw InvalidTerminfoException();
strings_.resize(offsets.size());
StringVec::iterator j (strings_.begin());
for (OffsetVec::iterator i (offsets.begin()); i != offsets.end(); ++i, ++j)
- if (*i != NoValue)
+ if (*i != NoValue && *i >= 0 && unsigned(*i) < stringPool_.size())
*j = &(stringPool_[0]) + *i;
+ else
+ *j = 0;
}
///////////////////////////////////////////////////////////////////////////