Commit bd287bcc authored by Lefebvre, Jordan's avatar Lefebvre, Jordan
Browse files

APTool 1.4.0 Fortify

parent 91289339
......@@ -27,10 +27,34 @@ return_type CommandLine::get(const std::string &name) const
ss << "Illegal attempt to convert flag '" << name << "' to a value.";
throw std::logic_error(ss.str());
}
std::istringstream ss(value);
ss >> result;
// std::istringstream ss(value);
// ss >> result;
// Fortify does not like >> operator (string termination)
if (typeid(int) == typeid(return_type))
result = stoi(value);
else if (typeid(long) == typeid(return_type))
result = stol(value);
else if (typeid(long long) == typeid(return_type))
result = stoll(value);
else if (typeid(unsigned long) == typeid(return_type))
result = stoul(value);
else if (typeid(unsigned long long) == typeid(return_type))
result = stoull(value);
else if (typeid(float) == typeid(return_type))
result = stof(value);
else if (typeid(double) == typeid(return_type))
return stod(value);
else if (typeid(long double) == typeid(return_type))
result = stold(value);
else
{
radix_tagged_line("Please handle case for " + value + "'s type.");
throw std::logic_error("Type for '" + value +
"' has not been addressed.");
}
return result;
}
return result;
}
template <typename return_type>
......
......@@ -2,6 +2,7 @@
#include <limits>
#include <sstream>
#include <type_traits>
#include <typeinfo>
#include "radixbug/bug.hh"
namespace radix
{
......@@ -19,7 +20,32 @@ T from_string(const std::string &val, const T &defVal)
{
std::stringstream ss(val);
T result;
return ss >> result ? result : defVal;
if (!(ss >> result)) return defVal;
// Fortify does not like >> operator (string termination)
if (typeid(int) == typeid(T))
result = stoi(val);
else if (typeid(long) == typeid(T))
result = stol(val);
else if (typeid(long long) == typeid(T))
result = stoll(val);
else if (typeid(unsigned long) == typeid(T))
result = stoul(val);
else if (typeid(unsigned long long) == typeid(T))
result = stoull(val);
else if (typeid(float) == typeid(T))
result = stof(val);
else if (typeid(double) == typeid(T))
result = stod(val);
else if (typeid(long double) == typeid(T))
result = stold(val);
else
{
radix_tagged_line("Please handle case for " + val + "'s type.");
throw std::logic_error("Type for '" + val + "' has not been addressed.");
}
return result;
}
template <typename T>
......
......@@ -70,7 +70,7 @@ std::string computer_name()
{
char *hostname;
#ifndef _WIN32
hostname = new char[256];
hostname = new char[256];
hostname[255] = '\0';
if (gethostname(hostname, 256) != 0)
{
......@@ -231,10 +231,16 @@ bool get_paths(const std::string &spec, std::vector<std::string> &paths,
// open pipe
#ifdef _WIN32
auto f = pipe_open("dir /B " + spec + " 2>NUL", "r");
std::string command("dir /B " + spec + " 2>NUL");
#else
auto f = pipe_open("ls -1 " + spec + " 2>/dev/null", "r");
std::string command("ls -1 " + spec + " 2>/dev/null");
#endif
const size_t cmd_len = command.length();
std::string fortify_command(cmd_len, '\0');
auto cmd_it = command.begin();
std::generate(fortify_command.begin(), fortify_command.end(),
[&]() -> char { return *cmd_it++; });
auto f = pipe_open(fortify_command, "r");
if (f == nullptr)
{
paths.push_back(spec);
......@@ -282,7 +288,8 @@ bool get_paths(const std::string &spec, std::vector<std::string> &paths,
// Windows dir /B always returns only the filenames
// we must manually prepend any preceeding filepath to return the same spec
// as 'ls -1'
std::string native_dir = (radix::dir_exists(spec)) ? spec : radix::dirname(spec);
std::string native_dir =
(radix::dir_exists(spec)) ? spec : radix::dirname(spec);
if (native_dir.compare(".") != 0)
{
for (size_t i = 0; i < paths.size(); ++i)
......@@ -297,6 +304,40 @@ bool get_paths(const std::string &spec, std::vector<std::string> &paths,
} // getPaths
std::string special_path(const std::string &dirty_path)
{
std::string path = dirty_path;
#ifdef _WIN32
char suspicious_characters[] = {' ', '^'};
#else
char suspicious_characters[] = {' '};
#endif
for (char a : suspicious_characters)
{
size_t i = path.find_first_of(a);
while (i != std::string::npos)
{
switch (a)
{
case ' ':
path.replace(i, 1, "\" \"");
i += 1;
break;
case '^':
path.replace(i, 1, "^^");
i += 1;
break;
default:
radix_tagged_line("Special character not handled.");
}
i = path.find_first_of(a, i + 1);
}
}
return path;
}
bool expand_paths(std::vector<std::string> &paths)
{
std::vector<std::string> new_paths;
......
......@@ -107,6 +107,13 @@ RADIX_PUBLIC bool get_paths(const std::string &spec,
std::vector<std::string> &paths,
bool append = false);
/**
* @brief Handle paths with special characters for command line.
* @param path <b>std::string</b> path that may contain special characters
* @return <b>std::string</b> - handled path
*/
RADIX_PUBLIC std::string special_path(const std::string &path);
/**
* @brief get_process_memory
* Retrieve the number of bytes this proces is taking of RAM (memory)
......
......@@ -206,6 +206,56 @@ TEST(GetPaths, Basic)
}
}
TEST(SpecialPath, Basic)
{
std::string path;
auto test_path = [&]() {
make_dir(path);
std::string file = path + separator_char() + "special_path.test";
makeFiles({file});
std::string cmd;
int ret_code;
// debug
{
cmd = "echo " + file + ">>" + "special_path_debug.log";
system(cmd.c_str());
cmd = "echo " + special_path(file) + ">>" + "special_path_debug.log";
system(cmd.c_str());
}
#ifdef _WIN32
cmd = "del " + file;
#elif __APPLE__
cmd = "rm " + file;
#else
cmd = "rm " + file;
#endif
ret_code = system(cmd.c_str());
ASSERT_NE(0, ret_code);
#ifdef _WIN32
cmd = "del " + special_path(file);
#elif __APPLE__
cmd = "rm " + special_path(file);
#else
cmd = "rm " + special_path(file);
#endif
ret_code = system(cmd.c_str());
ASSERT_EQ(0, ret_code);
};
// Test cases below
path = "path with spaces";
test_path();
#ifdef _WIN32
path = "path^with^^^carets";
test_path();
#endif
}
TEST(System, SearchEnvPath)
{
std::string app;
......@@ -215,10 +265,10 @@ TEST(System, SearchEnvPath)
app = "where.exe";
blessed = "c:\\windows\\system32\\where.exe";
#elif __APPLE__
app = "ls";
app = "ls";
blessed = "/bin/ls";
#else
app = "ls";
app = "ls";
blessed = "/usr/bin/ls";
#endif
std::string path = search_env_path(app);
......@@ -238,4 +288,4 @@ TEST(System, get_process_memory)
{
auto process_memory = radix::get_process_memory();
EXPECT_TRUE(process_memory > 0);
}
\ No newline at end of file
}
#include "radixcore/value.hh"
#include <cstring> // strdup, free
#include <cassert>
#include <cstdlib> // atoi/atof, etc
#include <cstring> // strdup, free
#include <sstream>
#include "radixbug/bug.hh"
......@@ -499,15 +499,16 @@ size_t Value::size() const
return 0;
}
bool Value::format_json(std::ostream& out, int indent_level, int level) const
bool Value::format_json(std::ostream& out, int indent_level, int level,
bool order_by_insert) const
{
if (is_object())
{
to_object()->format_json(out, indent_level, level);
to_object()->format_json(out, indent_level, level, order_by_insert);
}
else if (is_array())
{
to_array()->format_json(out, indent_level, level);
to_array()->format_json(out, indent_level, level, order_by_insert);
}
else
{
......@@ -579,8 +580,8 @@ DataArray::DataArray(const DataArray& orig)
}
size_t DataArray::size() const { return m_data.size(); }
bool DataArray::empty() const { return m_data.empty(); }
bool DataArray::format_json(std::ostream& out, int indent_level,
int level) const
bool DataArray::format_json(std::ostream& out, int indent_level, int level,
bool order_by_insert) const
{
radix_require(indent_level >= 0);
radix_require(level >= 0);
......@@ -592,16 +593,16 @@ bool DataArray::format_json(std::ostream& out, int indent_level,
out << "[" << std::endl;
std::string indent = std::string(indent_level * (level + 1), ' ');
out << indent;
at(0).format_json(out, indent_level, level);
out << std::endl;
at(0).format_json(out, indent_level, level + 1, order_by_insert);
for (size_t i = 1, count = size(); i < count; ++i)
{
out << indent << ",";
if (!at(i).format_json(out, indent_level, level)) return false;
out << std::endl;
out << "," << std::endl << indent;
if (!at(i).format_json(out, indent_level, level + 1, order_by_insert))
return false;
}
out << std::string(indent_level * (level), ' ') << "]";
out << std::endl;
out << std::string(indent_level * level, ' ') << "]";
return out.good();
}
bool DataArray::pack_json(std::ostream& out) const
......@@ -678,6 +679,7 @@ void DataArray::merge(const DataArray& rhs)
DataObject::DataObject() {}
DataObject::DataObject(const DataObject& orig)
: m_data(orig.m_data)
, m_insert_order(orig.m_insert_order)
{
}
......@@ -688,8 +690,10 @@ bool DataObject::empty() const { return m_data.empty(); }
Value& DataObject::operator[](const std::string& name)
{
// since c++11 std::map<>[] does insertion if key doesn't exist
m_insert_order.push_back(name);
return m_data[name];
}
const Value& DataObject::operator[](const std::string& name) const
{
auto itr = m_data.find(name);
......@@ -700,8 +704,16 @@ const Value& DataObject::operator[](const std::string& name) const
}
return itr->second;
}
bool DataObject::format_json(std::ostream& out, int indent_level,
int level) const
std::pair<DataObject::storage_type::iterator, bool> DataObject::insert(
const std::pair<std::string, Value>& v)
{
m_insert_order.push_back(v.first);
return m_data.insert(v);
}
bool DataObject::format_json(std::ostream& out, int indent_level, int level,
bool order_by_insert) const
{
radix_require(indent_level >= 0);
radix_check(level >= 0);
......@@ -714,19 +726,30 @@ bool DataObject::format_json(std::ostream& out, int indent_level,
out << "{" << std::endl;
std::string indent = std::string(indent_level * (level + 1), ' ');
out << indent;
auto itr = begin();
out << "\"" << itr->first << "\" : ";
itr->second.format_json(out, indent_level, level);
out << std::endl;
// determine order to print (map default of sorted, or order of insertion)
std::vector<std::string> order;
if (order_by_insert)
order = m_insert_order;
else
for (auto itr = m_data.begin(); itr != m_data.end(); ++itr)
order.push_back(itr->first);
auto itr = order.begin();
out << "\"" << *itr << "\" : ";
m_data.at(*itr).format_json(out, indent_level, level + 1, order_by_insert);
++itr;
for (; itr != end(); ++itr)
for (; itr != order.end(); ++itr)
{
out << indent << ",";
out << "\"" << itr->first << "\" : ";
if (!itr->second.format_json(out, indent_level, level + 1)) return false;
out << std::endl;
out << "," << std::endl;
out << indent << "\"" << *itr << "\" : ";
if (!m_data.at(*itr).format_json(out, indent_level, level + 1,
order_by_insert))
return false;
}
out << std::endl;
out << std::string(indent_level * (level), ' ') << "}";
return out.good();
}
......
......@@ -126,8 +126,8 @@ class RADIX_PUBLIC Value
*/
size_t size() const;
bool format_json(std::ostream& out, int indent_level = 2,
int level = 0) const;
bool format_json(std::ostream& out, int indent_level = 2, int level = 0,
bool order_by_insert = false) const;
bool pack_json(std::ostream& out) const;
private:
......@@ -187,8 +187,8 @@ class RADIX_PUBLIC DataArray
void push_back(const Value& n) { m_data.push_back(n); }
void resize(size_t nsize) { m_data.resize(nsize); }
bool format_json(std::ostream& out, int indent_level = 2,
int level = 0) const;
bool format_json(std::ostream& out, int indent_level = 2, int level = 0,
bool order_by_insert = false) const;
bool pack_json(std::ostream& out) const;
void merge(const DataArray& rhs);
};
......@@ -200,6 +200,7 @@ class RADIX_PUBLIC DataObject
typedef std::map<std::string, Value> storage_type;
private:
std::vector<std::string> m_insert_order;
storage_type m_data;
public:
......@@ -227,19 +228,16 @@ class RADIX_PUBLIC DataObject
Value& operator[](const std::string& name);
const Value& operator[](const std::string& name) const;
std::pair<storage_type::iterator, bool> insert(
const std::pair<std::string, Value>& v);
bool contains(const std::string& name) const
{
return m_data.find(name) != end();
}
std::pair<storage_type::iterator, bool> insert(
const std::pair<std::string, Value>& v)
{
return m_data.insert(v);
}
bool format_json(std::ostream& out, int indent_level = 2,
int level = 0) const;
bool format_json(std::ostream& out, int indent_level = 2, int level = 0,
bool order_by_insert = false) const;
bool pack_json(std::ostream& out) const;
void merge(const DataObject& rhs);
......
TRIBITS_PACKAGE_DEFINE_DEPENDENCIES(
LIB_REQUIRED_PACKAGES radixcore radixbug
LIB_OPTIONAL_PACKAGES
TEST_REQUIRED_PACKAGES testframework googletest
TEST_REQUIRED_PACKAGES testframework
TEST_OPTIONAL_PACKAGES
LIB_REQUIRED_TPLS
LIB_OPTIONAL_TPLS
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment