Limit log sanitation of string buffers to a maximum length to avoid printing invalid characters

This commit is contained in:
patrickvl 2019-06-15 16:30:23 +02:00
parent 59d0f36f2f
commit e150690646
3 changed files with 45 additions and 40 deletions

View File

@ -291,8 +291,8 @@ LOG_SANITIZE_HEADER(sanitized_char_pointer, char *)
return os << "NULL";
bool needsEscaping = false;
while (*v)
int max_length = container.max;
while (*v && max_length--)
if (needs_escape(*v++))
{
needsEscaping = true;
@ -301,13 +301,17 @@ LOG_SANITIZE_HEADER(sanitized_char_pointer, char *)
v = container.value;
os << hexstring32 << (uint32_t)v << " = \"";
max_length = container.max;
if (needsEscaping)
{
while (*v)
while (*v && max_length--)
output_char(os, *v++);
}
else
os << v;
else {
while (*v && max_length--) {
os << *v++;
}
}
return os << "\"";
}
@ -321,8 +325,8 @@ LOG_SANITIZE_HEADER(sanitized_wchar_pointer, wchar_t *)
return os << "NULL";
bool needsEscaping = false;
while (*v)
int max_length = container.max;
while (*v && max_length--)
if (needs_escape(*v++))
{
needsEscaping = true;
@ -331,9 +335,10 @@ LOG_SANITIZE_HEADER(sanitized_wchar_pointer, wchar_t *)
v = container.value;
os << hexstring32 << (uint32_t)v << " = \"";
max_length = container.max;
if (needsEscaping)
{
while (*v)
while (*v && max_length--)
output_wchar(os, *v++);
}
else
@ -341,7 +346,7 @@ LOG_SANITIZE_HEADER(sanitized_wchar_pointer, wchar_t *)
os << v; // TODO : FIXME - VS2015 doesn''t render this string (instead, it shows a hexadecimal memory address)
#else // For now, render unicode as ANSI (replacing non-printables with '?')
{
while (*v) {
while (*v && max_length--) {
output_char(os, *v <= 0xFF ? (char)*v : '?');
v++;
}

View File

@ -162,44 +162,44 @@ extern inline void output_wchar(std::ostream& os, wchar_t c);
// By default, sanitization functions simply return the given argument
// (type and value) which results in calls to standard output writers.
template<class T>
inline T _log_sanitize(T value)
inline T _log_sanitize(T value, int ignored_length = 0)
{
return value;
}
#if 0 // TODO FIXME : Disabled for now, as this is incorrectly called for INT types too
// Convert booleans to strings properly
inline const char * _log_sanitize(BOOL value)
inline const char * _log_sanitize(BOOL value, int ignored_length = 0)
{
return value ? "TRUE" : "FALSE";
}
#endif
// Macro to ease declaring a _log_sanitize overload (invokeable via C) for type T
#define LOG_SANITIZE_HEADER(C, T) \
std::ostream& operator<<( \
std::ostream& os, \
const Sane##C& container) \
#define LOG_SANITIZE(C, T) \
struct Sane##C \
{ \
T value; \
Sane##C(T _value) : value(_value) { } \
}; \
\
inline Sane##C C(T value) \
{ \
return Sane##C(value); \
} \
\
inline Sane##C _log_sanitize(T value) \
{ \
return C(value); \
} \
\
extern LOG_SANITIZE_HEADER(C, T) \
#define LOG_SANITIZE_HEADER(C, T) \
std::ostream& operator<<( \
std::ostream& os, \
const Sane##C& container) \
#define LOG_SANITIZE(C, T) \
struct Sane##C \
{ \
T value; \
int max; \
Sane##C(T _v, int _m = 80) : value(_v), max(_m) { } \
}; \
\
inline Sane##C C(T value, int max = 80) \
{ \
return Sane##C(value, max); \
} \
\
inline Sane##C _log_sanitize(T value, int max = 80) \
{ \
return C(value, max); \
} \
\
extern LOG_SANITIZE_HEADER(C, T) \
// Hex output (type safe)
// https://stackoverflow.com/questions/673240/how-do-i-print-an-unsigned-char-as-hex-in-c-using-ostream
@ -455,7 +455,7 @@ extern thread_local std::string _logThreadPrefix;
#define LOGRENDER_MEMBER_NAME(Member) << LOG_ARG_START << "."#Member << " : "
#define LOGRENDER_MEMBER(Member) LOGRENDER_MEMBER_NAME_VALUE("."#Member, value.Member)
#define LOGRENDER_MEMBER_TYPE(Type, Member) LOGRENDER_MEMBER_NAME(Member) << (Type)value.Member
#define LOGRENDER_MEMBER_SANITIZED(Member, MemberType) LOGRENDER_MEMBER_NAME(Member) << _log_sanitize((MemberType)value.Member)
#define LOGRENDER_MEMBER_SANITIZED(Member, MemberType, Length) LOGRENDER_MEMBER_NAME(Member) << _log_sanitize((MemberType)value.Member, Length)
// Macro to ease declaration of two render functions, for type and pointer-to-type :
#define LOGRENDER_HEADER(Type) LOGRENDER_HEADER_BY_PTR(Type); LOGRENDER_HEADER_BY_REF(Type);

View File

@ -391,7 +391,7 @@ LOGRENDER(LAUNCH_DATA_HEADER)
return os
LOGRENDER_MEMBER(dwLaunchDataType)
LOGRENDER_MEMBER(dwTitleId)
LOGRENDER_MEMBER_SANITIZED(szLaunchPath, char *)
LOGRENDER_MEMBER_SANITIZED(szLaunchPath, char *, /*Length=*/sizeof(value.szLaunchPath) / sizeof(value.szLaunchPath[0]))
LOGRENDER_MEMBER(dwFlags);
}
@ -399,8 +399,8 @@ LOGRENDER(LAUNCH_DATA_PAGE)
{
return os
LOGRENDER_MEMBER_NAME(Header) << &value.Header
LOGRENDER_MEMBER_SANITIZED(Pad, char *)
LOGRENDER_MEMBER_SANITIZED(LaunchData, char *);
LOGRENDER_MEMBER_SANITIZED(Pad, char *, /*Length=*/sizeof(value.Pad) / sizeof(value.Pad[0]))
LOGRENDER_MEMBER_SANITIZED(LaunchData, char *, /*Length=*/sizeof(value.LaunchData) / sizeof(value.LaunchData[0]));
}
LOGRENDER(MM_STATISTICS)
@ -431,7 +431,7 @@ LOGRENDER(STRING)
return os
LOGRENDER_MEMBER(Length)
LOGRENDER_MEMBER(MaximumLength)
LOGRENDER_MEMBER_SANITIZED(Buffer, char *);
LOGRENDER_MEMBER_SANITIZED(Buffer, char *, value.Length);
}
LOGRENDER(UNICODE_STRING)
@ -439,7 +439,7 @@ LOGRENDER(UNICODE_STRING)
return os
LOGRENDER_MEMBER(Length)
LOGRENDER_MEMBER(MaximumLength)
LOGRENDER_MEMBER_SANITIZED(Buffer, wchar_t *);
LOGRENDER_MEMBER_SANITIZED(Buffer, wchar_t *, value.Length);
}
}; // end of namespace xboxkrnl;