]> source.dussan.org Git - rspamd.git/commitdiff
Add more types
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 11 Nov 2015 14:32:41 +0000 (14:32 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 11 Nov 2015 14:32:41 +0000 (14:32 +0000)
clang-plugin/printf_check.cc

index 37e8dc3998992452fb244218dfa3af2f6804842c..7f20bdaac38249c53acaf916fecb2e87a98503d8 100644 (file)
@@ -22,6 +22,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <sys/types.h>
 #include "printf_check.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/Expr.h"
@@ -31,6 +32,9 @@
 #include <vector>
 #include <sstream>
 #include <ctype.h>
+#include <signal.h>
+#include <assert.h>
+#include <cstdint>
 
 using namespace clang;
 
@@ -51,6 +55,12 @@ namespace rspamd {
                        struct PrintfArgChecker *ctx);
        static bool long_double_arg_handler (const Expr *arg,
                        struct PrintfArgChecker *ctx);
+       static bool pointer_arg_handler (const Expr *arg,
+                       struct PrintfArgChecker *ctx);
+       static bool pid_arg_handler (const Expr *arg,
+                       struct PrintfArgChecker *ctx);
+       static bool int64_arg_handler (const Expr *arg,
+                       struct PrintfArgChecker *ctx);
 
        using arg_parser_t = bool (*) (const Expr *, struct PrintfArgChecker *);
 
@@ -118,6 +128,15 @@ namespace rspamd {
                        case 'c':
                                return llvm::make_unique<PrintfArgChecker> (char_arg_handler,
                                                this->pcontext);
+                       case 'p':
+                               return llvm::make_unique<PrintfArgChecker> (pointer_arg_handler,
+                                               this->pcontext);
+                       case 'P':
+                               return llvm::make_unique<PrintfArgChecker> (pid_arg_handler,
+                                               this->pcontext);
+                       case 'L':
+                               return llvm::make_unique<PrintfArgChecker> (int64_arg_handler,
+                                               this->pcontext);
                        default:
                                llvm::errs () << "unknown parser flag: " << type << "\n";
                                break;
@@ -455,6 +474,9 @@ namespace rspamd {
                                         BuiltinType::Kind::Int},
                                        "%z");
                }
+               else {
+                       assert (0);
+               }
 
                return true;
        }
@@ -476,4 +498,64 @@ namespace rspamd {
                                {BuiltinType::Kind::LongDouble},
                                "%F or %G");
        }
+       static bool
+       pid_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
+       {
+               if (sizeof (pid_t) == sizeof (long)) {
+                       return check_builtin_type (arg,
+                                       ctx,
+                                       {BuiltinType::Kind::ULong,
+                                        BuiltinType::Kind::Long},
+                                       "%P");
+               }
+               else if (sizeof (pid_t) == sizeof (int)) {
+                       return check_builtin_type (arg,
+                                       ctx,
+                                       {BuiltinType::Kind::UInt,
+                                        BuiltinType::Kind::Int},
+                                       "%P");
+               }
+               else {
+                       assert (0);
+               }
+       }
+
+       static bool
+       pointer_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
+       {
+               auto type = arg->getType ().split ().Ty;
+
+               if (!type->isPointerType ()) {
+                       print_error (
+                                       std::string ("bad pointer argument for %p: ") +
+                                                       arg->getType ().getAsString (), arg, ctx->past);
+                       return false;
+               }
+
+               return true;
+       }
+
+       static bool
+       int64_arg_handler (const Expr *arg, struct PrintfArgChecker *ctx)
+       {
+               if (sizeof (int64_t) == sizeof (long long)) {
+                       return check_builtin_type (arg,
+                                       ctx,
+                                       {BuiltinType::Kind::ULongLong,
+                                        BuiltinType::Kind::LongLong},
+                                       "%L");
+               }
+               else if (sizeof (int64_t) == sizeof (long)) {
+                       return check_builtin_type (arg,
+                                       ctx,
+                                       {BuiltinType::Kind::ULong,
+                                        BuiltinType::Kind::Long},
+                                       "%z");
+               }
+               else {
+                       assert (0);
+               }
+
+               return true;
+       }
 };