This commit is contained in:
Themaister 2011-02-25 12:57:50 +01:00
parent eed83fa4ff
commit 4655c2d469
7 changed files with 189 additions and 43 deletions

View File

@ -4,8 +4,14 @@
#include <nall/concept.hpp>
#undef foreach
#define foreach(iter, object) \
#define foreach2(iter, object) foreach3(iter, object, foreach_counter)
#define foreach3(iter, object, foreach_counter) \
for(unsigned foreach_counter = 0, foreach_limit = container_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
for(typeof(object[0]) &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
#define foreach_impl(...) foreach_decl(__VA_ARGS__, foreach3(__VA_ARGS__), foreach2(__VA_ARGS__), foreach_too_few_arguments)
#define foreach_decl(_1, _2, _3, N, ...) N
#define foreach(...) foreach_impl(__VA_ARGS__)
#endif

32
nall/public_cast.hpp Normal file
View File

@ -0,0 +1,32 @@
#ifndef NALL_PUBLIC_CAST_HPP
#define NALL_PUBLIC_CAST_HPP
//this is a proof-of-concept-*only* C++ access-privilege elevation exploit.
//this code is 100% legal C++, per C++98 section 14.7.2 paragraph 8:
//"access checking rules do not apply to names in explicit instantiations."
//usage example:
//struct N { typedef void (Class::*)(); };
//template class public_cast<N, &Class::Reference>;
//(class.*public_cast<N>::value);
//Class::Reference may be public, protected or private
//Class::Reference may be a function, object or variable
namespace nall {
template<typename T, typename T::type... P> struct public_cast;
template<typename T> struct public_cast<T> {
static typename T::type value;
};
template<typename T> typename T::type public_cast<T>::value;
template<typename T, typename T::type P> struct public_cast<T, P> {
static typename T::type value;
};
template<typename T, typename T::type P> typename T::type public_cast<T, P>::value = public_cast<T>::value = P;
}
#endif

103
nall/reference_array.hpp Normal file
View File

@ -0,0 +1,103 @@
#ifndef NALL_REFERENCE_ARRAY_HPP
#define NALL_REFERENCE_ARRAY_HPP
#include <type_traits>
#include <nall/bit.hpp>
#include <nall/concept.hpp>
namespace nall {
template<typename T> struct reference_array {
protected:
typedef typename std::remove_reference<T>::type *Tptr;
Tptr *pool;
unsigned poolsize, buffersize;
public:
unsigned size() const { return buffersize; }
unsigned capacity() const { return poolsize; }
void reset() {
if(pool) free(pool);
pool = 0;
poolsize = 0;
buffersize = 0;
}
void reserve(unsigned newsize) {
if(newsize == poolsize) return;
pool = (Tptr*)realloc(pool, newsize * sizeof(T));
poolsize = newsize;
buffersize = min(buffersize, newsize);
}
void resize(unsigned newsize) {
if(newsize > poolsize) reserve(bit::round(newsize));
buffersize = newsize;
}
void append(const T data) {
unsigned index = buffersize++;
if(index >= poolsize) resize(index + 1);
pool[index] = &data;
}
template<typename... Args> reference_array(Args&... args) : pool(0), poolsize(0), buffersize(0) {
construct(args...);
}
~reference_array() {
reset();
}
reference_array& operator=(const reference_array &source) {
if(pool) free(pool);
buffersize = source.buffersize;
poolsize = source.poolsize;
pool = (Tptr*)malloc(sizeof(T) * poolsize);
memcpy(pool, source.pool, sizeof(T) * buffersize);
return *this;
}
reference_array& operator=(const reference_array &&source) {
if(pool) free(pool);
pool = source.pool;
poolsize = source.poolsize;
buffersize = source.buffersize;
source.pool = 0;
source.reset();
return *this;
}
inline T operator[](unsigned index) {
if(index >= buffersize) throw "reference_array[] out of bounds";
return *pool[index];
}
inline const T operator[](unsigned index) const {
if(index >= buffersize) throw "reference_array[] out of bounds";
return *pool[index];
}
private:
void construct() {
}
void construct(const reference_array &source) {
operator=(source);
}
void construct(const reference_array &&source) {
operator=(std::move(source));
}
template<typename... Args> void construct(T data, Args&... args) {
append(data);
construct(args...);
}
};
template<typename T> struct has_size<reference_array<T>> { enum { value = true }; };
}
#endif

View File

@ -71,7 +71,7 @@ namespace nall {
inline ~string();
inline bool readfile(const char*);
inline bool readfile(const string&);
inline string& replace (const char*, const char*);
inline string& qreplace(const char*, const char*);

View File

@ -69,8 +69,11 @@ inline intmax_t integer(const char *str) {
intmax_t result = 0;
bool negate = false;
//check for negation
if(*str == '-') {
//check for sign
if(*str == '+') {
negate = false;
str++;
} else if(*str == '-') {
negate = true;
str++;
}

View File

@ -252,7 +252,7 @@ string::~string() {
if(data) free(data);
}
bool string::readfile(const char *filename) {
bool string::readfile(const string &filename) {
assign("");
#if !defined(_WIN32)

View File

@ -50,10 +50,10 @@ inline string integer(intmax_t value) {
result[x] = buffer[y];
}
return result;
return (const char*)result;
}
template<unsigned length> inline string linteger(intmax_t value) {
template<unsigned length_> inline string linteger(intmax_t value) {
bool negative = value < 0;
if(negative) value = abs(value);
@ -68,7 +68,8 @@ template<unsigned length> inline string linteger(intmax_t value) {
buffer[size++] = negative ? '-' : '+';
buffer[size] = 0;
char result[length + 1];
unsigned length = (length_ == 0 ? size : length_);
char result[64];
memset(result, ' ', length);
result[length] = 0;
@ -76,10 +77,10 @@ template<unsigned length> inline string linteger(intmax_t value) {
result[x] = buffer[y];
}
return result;
return (const char*)result;
}
template<unsigned length> inline string rinteger(intmax_t value) {
template<unsigned length_> inline string rinteger(intmax_t value) {
bool negative = value < 0;
if(negative) value = abs(value);
@ -94,7 +95,8 @@ template<unsigned length> inline string rinteger(intmax_t value) {
buffer[size++] = negative ? '-' : '+';
buffer[size] = 0;
char result[length + 1];
unsigned length = (length_ == 0 ? size : length_);
char result[64];
memset(result, ' ', length);
result[length] = 0;
@ -102,7 +104,7 @@ template<unsigned length> inline string rinteger(intmax_t value) {
result[x] = buffer[y];
}
return result;
return (const char*)result;
}
inline string decimal(uintmax_t value) {
@ -124,10 +126,10 @@ inline string decimal(uintmax_t value) {
result[x] = buffer[y];
}
return &result[0];
return (const char*)result;
}
template<unsigned length> inline string ldecimal(uintmax_t value) {
template<unsigned length_> inline string ldecimal(uintmax_t value) {
char buffer[64];
unsigned size = 0;
@ -138,7 +140,8 @@ template<unsigned length> inline string ldecimal(uintmax_t value) {
} while(value);
buffer[size] = 0;
char result[length + 1];
unsigned length = (length_ == 0 ? size : length_);
char result[64];
memset(result, ' ', length);
result[length] = 0;
@ -146,10 +149,10 @@ template<unsigned length> inline string ldecimal(uintmax_t value) {
result[x] = buffer[y];
}
return result;
return (const char*)result;
}
template<unsigned length> inline string rdecimal(uintmax_t value) {
template<unsigned length_> inline string rdecimal(uintmax_t value) {
char buffer[64];
unsigned size = 0;
@ -160,7 +163,8 @@ template<unsigned length> inline string rdecimal(uintmax_t value) {
} while(value);
buffer[size] = 0;
char result[length + 1];
unsigned length = (length_ == 0 ? size : length_);
char result[64];
memset(result, ' ', length);
result[length] = 0;
@ -168,53 +172,51 @@ template<unsigned length> inline string rdecimal(uintmax_t value) {
result[x] = buffer[y];
}
return result;
return (const char*)result;
}
template<unsigned length> inline string hex(uintmax_t value) {
string output;
unsigned offset = 0;
template<unsigned length_> inline string hex(uintmax_t value) {
char buffer[64];
unsigned size = 0;
//render string backwards, as we do not know its length yet
do {
unsigned n = value & 15;
output[offset++] = n < 10 ? '0' + n : 'a' + n - 10;
buffer[size++] = n < 10 ? '0' + n : 'a' + n - 10;
value >>= 4;
} while(value);
while(offset < length) output[offset++] = '0';
output[offset--] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[64];
memset(result, '0', length);
result[length] = 0;
//reverse the string in-place
for(unsigned i = 0; i < (offset + 1) >> 1; i++) {
char temp = output[i];
output[i] = output[offset - i];
output[offset - i] = temp;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
result[x] = buffer[y];
}
return output;
return (const char*)result;
}
template<unsigned length> inline string binary(uintmax_t value) {
string output;
unsigned offset = 0;
template<unsigned length_> inline string binary(uintmax_t value) {
char buffer[256];
unsigned size = 0;
do {
unsigned n = value & 1;
output[offset++] = '0' + n;
buffer[size++] = '0' + n;
value >>= 1;
} while(value);
while(offset < length) output[offset++] = '0';
output[offset--] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[64];
memset(result, '0', length);
result[length] = 0;
for(unsigned i = 0; i < (offset + 1) >> 1; i++) {
char temp = output[i];
output[i] = output[offset - i];
output[offset - i] = temp;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
result[x] = buffer[y];
}
return output;
return (const char*)result;
}
//using sprintf is certainly not the most ideal method to convert