소스 검색

More primitive types parsers

tags/1.1.0
Vsevolod Stakhov 8 년 전
부모
커밋
ac3d14dbdc
1개의 변경된 파일213개의 추가작업 그리고 1개의 파일을 삭제
  1. 213
    1
      clang-plugin/printf_check.cc

+ 213
- 1
clang-plugin/printf_check.cc 파일 보기

@@ -41,6 +41,16 @@ namespace rspamd {
struct PrintfArgChecker *ctx);
static bool int_arg_handler (const Expr *arg,
struct PrintfArgChecker *ctx);
static bool long_arg_handler (const Expr *arg,
struct PrintfArgChecker *ctx);
static bool size_arg_handler (const Expr *arg,
struct PrintfArgChecker *ctx);
static bool char_arg_handler (const Expr *arg,
struct PrintfArgChecker *ctx);
static bool double_arg_handler (const Expr *arg,
struct PrintfArgChecker *ctx);
static bool long_double_arg_handler (const Expr *arg,
struct PrintfArgChecker *ctx);

using arg_parser_t = bool (*) (const Expr *, struct PrintfArgChecker *);

@@ -58,10 +68,16 @@ namespace rspamd {
public:
int width;
int precision;
bool is_unsigned;
ASTContext *past;

PrintfArgChecker (arg_parser_t _p, ASTContext *_ast) :
parser(_p), past(_ast) {}
parser(_p), past(_ast)
{
width = 0;
precision = 0;
is_unsigned = false;
}
virtual ~PrintfArgChecker () {}

bool operator () (const Expr *e)
@@ -85,6 +101,23 @@ namespace rspamd {
case 'd':
return llvm::make_unique<PrintfArgChecker>(int_arg_handler,
this->pcontext);
case 'z':
return llvm::make_unique<PrintfArgChecker> (size_arg_handler,
this->pcontext);
case 'l':
return llvm::make_unique<PrintfArgChecker> (long_arg_handler,
this->pcontext);
case 'f':
case 'g':
return llvm::make_unique<PrintfArgChecker> (double_arg_handler,
this->pcontext);
case 'F':
case 'G':
return llvm::make_unique<PrintfArgChecker> (long_double_arg_handler,
this->pcontext);
case 'c':
return llvm::make_unique<PrintfArgChecker> (char_arg_handler,
this->pcontext);
default:
llvm::errs () << "unknown parser flag: " << type << "\n";
break;
@@ -366,4 +399,183 @@ namespace rspamd {

return true;
}

static bool
long_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
auto type = arg->getType ().split ().Ty;

auto desugared_type = type->getUnqualifiedDesugaredType ();

if (!desugared_type->isIntegerType ()) {
print_error (
std::string ("bad integer argument for %l arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
else if (!desugared_type->isBuiltinType ()) {
print_error (
std::string ("bad integer argument for %l arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
auto kind = builtin_type->getKind ();

if (kind != BuiltinType::Kind::ULong &&
kind != BuiltinType::Kind::Long) {
print_error (
std::string ("bad integer argument for %l arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

return true;
}

static bool
char_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
auto type = arg->getType ().split ().Ty;

auto desugared_type = type->getUnqualifiedDesugaredType ();

if (!desugared_type->isCharType ()) {
print_error (
std::string ("bad char argument for %c arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
else if (!desugared_type->isBuiltinType ()) {
print_error (
std::string ("bad char argument for %c arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
auto kind = builtin_type->getKind ();

if (kind != BuiltinType::Kind::UChar &&
kind != BuiltinType::Kind::SChar) {
print_error (
std::string ("bad char argument for %c arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

return true;
}

static bool
size_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
auto type = arg->getType ().split ().Ty;

auto desugared_type = type->getUnqualifiedDesugaredType ();

if (!desugared_type->isIntegerType ()) {
print_error (
std::string ("bad integer argument for %z arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
else if (!desugared_type->isBuiltinType ()) {
print_error (
std::string ("bad integer argument for %z arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
auto kind = builtin_type->getKind ();

if (sizeof (size_t) == sizeof (long)) {
if (kind != BuiltinType::Kind::ULong &&
kind != BuiltinType::Kind::Long) {
print_error (
std::string ("bad integer argument for %z arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
}
else if (sizeof (size_t) == sizeof (int)) {
if (kind != BuiltinType::Kind::UInt &&
kind != BuiltinType::Kind::Int) {
print_error (
std::string ("bad integer argument for %z arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
}

return true;
}

static bool
double_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
auto type = arg->getType ().split ().Ty;

auto desugared_type = type->getUnqualifiedDesugaredType ();

if (!desugared_type->isRealFloatingType ()) {
print_error (
std::string ("bad double argument for %f or %g arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
else if (!desugared_type->isBuiltinType ()) {
print_error (
std::string ("bad double argument for %f or %g arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
auto kind = builtin_type->getKind ();

if (kind != BuiltinType::Kind::Double) {
print_error (
std::string ("bad double argument for %f or %g arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

return true;
}

static bool
long_double_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
{
auto type = arg->getType ().split ().Ty;

auto desugared_type = type->getUnqualifiedDesugaredType ();

if (!desugared_type->isRealFloatingType ()) {
print_error (
std::string ("bad long double argument for %F or %G arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}
else if (!desugared_type->isBuiltinType ()) {
print_error (
std::string ("bad long double argument for %F or %G arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

auto builtin_type = dyn_cast<BuiltinType> (desugared_type);
auto kind = builtin_type->getKind ();

if (kind != BuiltinType::Kind::LongDouble) {
print_error (
std::string ("bad long double argument for %F or %G arg: ") +
arg->getType ().getAsString (), arg, ctx->past);
return false;
}

return true;
}
};

Loading…
취소
저장