å€ãã®çŸä»£èšèªãšæ¯èŒããŠãCèšèªã¯ãã°ãã°éåžžã«åå§çã§å®å
šã§ã¯ãªãããã§ãã ãŸããèšèªã«é¢ããããããäžæºã®1ã€ã¯ãã³ãŒããããã®å
éšè¡šçŸãžã®ã¢ã¯ã»ã¹ãäžå¯èœã§ããããšã§ãã ä»ã®èšèªã§ã¯ãããã¯äŒçµ±çã«ãªãã¬ã¯ã·ã§ã³ãªã©ã®ã¡ã«ããºã ã«ãã£ãŠè¡ãããéåžžã«äœ¿ããããã§ãã
ããã§ããlibclangã®ç»å Žã«ãããã³ã³ãã€ã«æã«çŽæ¥ç¬èªã®ã¢ãã©ã€ã¶ãŒãšã³ãŒããžã§ãã¬ãŒã¿ãŒãèšè¿°ã§ããããã«ãªããäœæ¥ã®åæ段éã§ããªãã®æ°ã®åé¡ã解æ¶ãããŸããã äžè¬èšç»ã®éçåæããŒã«ïŒã«ããŒçãclang-scanïŒãç¹å®ã®ãããžã§ã¯ãã®åæããŒã«ãããã³ã³ãŒãèšè¿°ã®èŠåŸã®çµã¿åããã«ãããCã³ãŒãã®å質ãšå®å
šæ§ã倧å¹
ã«åäžããŸãã ãã¡ãããããã¯haskellãrustãæäŸããä¿èšŒãäžãããã®ã§ã¯ãããŸããããç¹ã«å¥ã®èšèªã§å·šå€§ãªãããžã§ã¯ããæžãæããããšãéçŸå®çãªã¿ã¹ã¯ã§ããå Žåãéçºããã»ã¹ã倧å¹
ã«æé©åã§ããŸãã
ãã®èšäºã§ã¯ãprintfã«äŒŒãé¢æ°ã®éçåŒæ°ãã©ã°ã€ã³åœ¢åŒåŒæ°ãäœæããçµéšãå
±æããããšæããŸãã ãã©ã°ã€ã³ã®äœæäžã«ãlibclangã®ãœãŒã¹ãšdoxygenã®ããã¥ã¡ã³ããããæãäžããªããã°ãªããªãã£ãã®ã§ããã®åä»ãªéãæ©ãããããæ
å ±ãåéããã®ã«æéãè²»ãã䟡å€ããããã©ããã¯ãŸã ããããªã人ã®ããã«ãããã€ãã®ã¬ãã¥ãŒãè¡ãããšãæçšã§ããããšãããããŸããã ãã®èšäºã«ã¯åçã¯ãªããååãããŠãã³ãŒã³ã®åçãããããŸãããããããªããã
åé¡ã®å£°æ
é¢æ°ã®ãããªprintfãåæããåé¡ã¯ç§ã®ãããžã§ã¯ãïŒ
https://rspamd.com ïŒã«é·ãéãããŸããïŒlibcããã®æšæºã®printfã¯å€ãã®çç±ã§ç§ã«é©åããŸããã§ããïŒ
- ãããã¡ãŒã«åºåãããšããprintfïŒ3ïŒã¯ã巚倧ãªãã«çµäºæååãå«ã¿ãå®å
ãããã¡ãŒãéåžžã«å°ããå Žåã§ãããã©ãŒãããæååå
šäœãå
šäœãšããŠè§£æããããšããŸã
snprintf(buf, 16, "%s", str)
é·ãã²ã ãã®ãããªè¡åã¯ç§ã«ã¯åœ¹ã«ç«ããªãã£ã - printfã¯åºå®é·æŽæ°ïŒuint32_tãuitn64_tïŒãéåžžã«äžååã«ç解ããŸã
- æ«å°Ÿã«ã\ 0ãã®ãªãåºå®é·æååãªã©ãç¬èªã®ããŒã¿æ§é ãå°å·ãããã£ã
- 16é²ãšã³ã³ãŒãã£ã³ã°ã人éãèªããæŽæ°ãªã©ããããé«åºŠãªããã©ãŒããããã©ã°ãå¿
èŠã§ããã
- èªåã®ããŒã¿æ§é ãããšãã°ãèªåçã«æ¡åŒµå¯èœãªè¡ã§å°å·ã§ããããã«ãããã£ã
ãã®ãããäžåºŠnginxããprintfãååŸããŠãã¿ã¹ã¯ã«åãããŠèª¿æŽããŸããã ãµã³ãã«ã³ãŒãã¯
ãã¡ãã«ãããŸã ã ãã®ã¢ãããŒãã«ã¯1ã€ã®æ¬ ç¹ããããŸããã³ã³ãã€ã©ããã®æšæºã¯ãšãªæååã¢ãã©ã€ã¶ãŒã®æäœãå®å
šã«ç¡å¹ã«ãªããéçãªäžè¬çãªã¢ãã©ã€ã¶ãŒã¯ã©ã®åŒæ°ãäœãæå³ããã®ãç解ã§ããŸããã ãã ãããã®ã¿ã¹ã¯ã¯ãlibclangãä»ããŠæäŸãããã³ã³ãã€ã©ã®æœè±¡æ§æããªãŒïŒASTïŒã䜿çšããŠçæ³çã«è§£æ±ºãããŸãã
ASTåŠçãã©ã°ã€ã³ã¯ã次ã®ã¿ã¹ã¯ãå®è¡ããå¿
èŠããããŸãã
- ã¯ãšãªæååã解æãããããããã¹ãŠã®'ïŒ
'åŒæ°ãæœåºããŸã
- æž¡ãããã¯ãšãªæååãšé¢æ°ã®åŒæ°ã®æ°ã®æ¯èŒ
- ååŒæ°ã®åã確èªããæ©èœïŒè€ååãå«ãïŒ
- ç°ãªãäœçœ®ã§ã¯ãšãªæååãåãå
¥ããé¢æ°ããã¹ãããæ©èœïŒããšãã°ã printf / fprintf / snprintf ïŒ
ãã©ã°ã€ã³ã®ã³ã³ãã€ã«ãšåäœ
ã€ã³ã¿ãŒãããäžã§libclangã䜿çšããã®ã«ååãªäŸããããŸããããããã®ã»ãšãã©ã¯åŒã®åæãããå®çŸ©ã®åæã«å°å¿µããŠããŸããããã«ãäœããã®çç±ã§ãå€ãã®äŸãPythonã§æžãããŠãããåªããïŒç§ã®æèŠã§ã¯ïŒC + 11絶察ã«ããããããŸããã§ããïŒãã ããC ++ã§ã®ãããã¿ã€ãã®ã³ã³ãã€ã«æéãäž»ãªé倧ãªæ¬ ç¹ã§ãïŒã
ç§ãæåã«ééããåé¡ã¯ãllvmã®ç°ãªãããŒãžã§ã³ãç°ãªãAPIãæäŸããããšã§ããã ããã«ãããšãã°ãmacportsãä»ããŠã€ã³ã¹ããŒã«ãããosx llvmã¢ã»ã³ããªã¯ããããŒãŠã§ã€ããšããèšèããåäœäžèœã§ããããšãå€æããŸããã ãããã£ãŠãç§ã¯ã¡ããã©linuxãµã³ãããã¯ã¹ã«llvmãã€ã³ã¹ããŒã«ãããã®ããŒãžã§ã³ïŒ3.7ïŒã§ç¹ã«åäœããŸããã ãã ãããã®ã³ãŒãã¯3.6以éã§ãåäœããã¯ãã§ãã
2çªç®ã®åé¡ã¯ããã«ãã·ã¹ãã ã§ãã ç§ã®ãããžã§ã¯ãã¯cmakeã䜿çšããŠããã®ã§ã確ãã«ãã©ã°ã€ã³ããã«ãããããã«ããã䜿çšãããã£ãã§ãã ã¢ã€ãã¢ã¯ããªãã·ã§ã³ããªã³ã«ããŠãã©ã°ã€ã³ããã«ãããããã䜿çšããŠæ®ãã®ã³ãŒãããã«ããããšãããã®ã§ããã ãŸããcmakeã®å Žåãšåæ§ã«ãã·ã¹ãã å
ã§llvmãšlibclangãèŠã€ããããã®ããã±ãŒãžãäœæããCXXãã©ã°ãèšå®ããå¿
èŠããããŸããïŒããšãã°ãc ++ 11æšæºã®çµã¿èŸŒã¿ïŒã æ®å¿µãªãããosxã§llvmã䜿ããªããããæ¥åžžã®äœæ¥ã«äœ¿çšããŠããçŽ æŽããã
CLion IDEãšã®çµ±åãå®å
šã«äžæãããããIDEãæäŸããã¢ããªã³ããã®ä»ã®ã¢ã¡ããã£ãªãã§ã³ãŒããæžãå¿
èŠããããŸããã
ãã©ã°ã€ã³ã®ã³ã³ãã€ã«ã¯ãç¹å¥ãªåé¡ãåŒãèµ·ãããŸããã§ããã
FIND_PACKAGE(LLVM REQUIRED) SET(CLANGPLUGINSRC plugin.cc printf_check.cc) ADD_LIBRARY(rspamd-clang SHARED ${CLANGPLUGINSRC}) SET_TARGET_PROPERTIES(rspamd-clang PROPERTIES COMPILE_FLAGS "${LLVM_CXX_FLAGS} ${LLVM_CPP_FLAGS} ${LLVM_C_FLAGS}" INCLUDE_DIRECTORIES ${LIBCLANG_INCLUDE_DIR} LINKER_LANGUAGE CXX) TARGET_LINK_LIBRARIES(rspamd-clang ${LIBCLANG_LIBRARIES}) LINK_DIRECTORIES(${LLVM_LIBRARY_DIRS})
ããããæ®ãã®ã³ãŒãã§åäœããããã«ãããå«ãããšãåé¡ããããŸããã 第äžã«ãcmakeã¯ãäœããã®çç±ã§ã³ã³ãã€ã©ãªãã·ã§ã³ãã°ã«ãŒãåãã
-Xclang opt1 -Xclang opt2
ã
-Xclang opt1 opt2
ã«
-Xclang opt1 opt2
ãã³ã³ãã€ã«ãå®å
šã«
-Xclang opt1 opt2
é¡èãªäººå·¥ç¥èœã瀺ããŸããã ãœãªã¥ãŒã·ã§ã³ã¯
CMAKE_C_FLAGS
çŽæ¥ã€ã³ã¹ããŒã«ããããšã§
CMAKE_C_FLAGS
ã
IF (ENABLE_CLANG_PLUGIN MATCHES "ON") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Xclang -load -Xclang ${CMAKE_CURRENT_BINARY_DIR}/../clang-plugin/librspamd-clang.so -Xclang -add-plugin -Xclang rspamd-ast") ENDIF ()
ã芧ã®ãšãããçµæã®ã©ã€ãã©ãªãžã®ãã¹ãæ瀺çã«æå®ããå¿
èŠããããŸãããããã«ãããosxïŒ.soã®ä»£ããã«.dylibã䜿çšãããŸãïŒã§ã·ã¹ãã ãç Žæããå¯èœæ§ããããŸããããããã¯osxã§llvmã䜿çšã§ããªããããéèŠãªèŠçŽ ã§ã¯ãããŸããã§ããã 2çªç®ã®åé¡ã¯ãã»ãšãã©ãã¹ãŠã®äŸã§æšå¥šãããŠããããã«
-Xclang -plugin
ãæå®ãããšãclangã¯ãœãŒã¹ã®ã³ã³ãã€ã«ãåæ¢ãïŒã€ãŸãããªããžã§ã¯ããã¡ã€ã«ãçæããªãïŒãåæã®ã¿ãå®è¡ããããšã§ãã
-Xclang -plugin
ã¯ã
-Xclang -plugin
ã
-Xclang -add-plugin
ã«çœ®ãæããããšã§ãããããã¯ãGoogleã®çºè¡ã«é¢ããããã€ãã®çæ³ã®åŸã«èŠã€ãããŸããã
ãã©ã°ã€ã³ãæžã
ãã®ããŒãã§ã¯ããã©ã°ã€ã³ã®äœæã®åºæ¬ã«ããŸãçŠç¹ãåœãŠãããããŸãããããã«ã¯å€ãã®è³æãè²»ããããŠããŸãã èŠããã«ããã©ã°ã€ã³ã¯éçã¡ãœãã
clang::FrontendPluginRegistry::Add
ã䜿çšããŠäœæãããclangã®ãã©ã°ã€ã³ãç»é²ããŸãã ãã®ã¡ãœããã¯å®åçã§ããã
clang::PluginASTAction
ãç¶æ¿ããã¯ã©ã¹ã¿ã€ããåãããã®äžã«å¿
èŠãªã¡ãœãããå®çŸ©ããŸãã
class RspamdASTAction : public PluginASTAction { protected: std::unique_ptr <ASTConsumer> CreateASTConsumer (CompilerInstance &CI, llvm::StringRef) override { return llvm::make_unique<RspamdASTConsumer> (CI); } bool ParseArgs (const CompilerInstance &CI, const std::vector <std::string> &args) override { return true; } void PrintHelp (llvm::raw_ostream &ros) { ros << "Nothing here\n"; } }; static FrontendPluginRegistry::Add <rspamd::RspamdASTAction> X ("rspamd-ast", "rspamd ast checker");
äž»ãªèå³æ·±ãã¡ãœããã¯
CreateASTConsumer
ã¡ãœããã§ãããã®ã¡ãœããã¯ãã³ã³ãã€ã©ãŒãã³ãŒããæ§æããªãŒã«å€æãã段éã§ãçµæã®ãªããžã§ã¯ããåŒã³åºãå¿
èŠãããããšãclangã«äŒããŸãã ãã以éã®äœæ¥ã¯ãã¹ãŠASTConsumerã§è¡ãããASTConsumerã¯
HandleTranslationUnit
ã¡ãœãããå®çŸ©ããŸãã
HandleTranslationUnit
ã¡ãœããã¯ãå®éã«ã¯æ§æããªãŒã®ã³ã³ããã¹ããååŸããŸãã
CompilerInstance
ããšã©ãŒãèŠåãçæãããªã©ãã³ã³ãã€ã©ãå¶åŸ¡ããããã«äœ¿çšãããŸããããã¯ããã©ã°ã€ã³ãæäœãããšãã«éåžžã«äŸ¿å©ã§ãã ASTConsumerå
šäœã¯æ¬¡ã®ãšããã§ãã
class RspamdASTConsumer : public ASTConsumer { CompilerInstance &Instance; public: RspamdASTConsumer (CompilerInstance &Instance) : Instance (Instance) { } void HandleTranslationUnit (ASTContext &context) override { rspamd::PrintfCheckVisitor v(&context, Instance); v.TraverseDecl (context.getTranslationUnitDecl ()); } };
ããã§ã¯ãããªãŒã®ããŒãã蚪åããã³ã³ãã€ã«ããªãŒãèµ°æ»ããASTVisitorãäœæããŸãã å®éããã®ã¯ã©ã¹ã§ã¯ããã¹ãŠã®äœæ¥ã¯é¢æ°åŒã³åºãã®åæã§è¡ãããŸãã ãã®ã¯ã©ã¹ã¯éåžžã«ç°¡åã«å®çŸ©ãããŠããŸãïŒ
pimplã®ã€ãã£ãªã ã䜿çšïŒïŒ
class PrintfCheckVisitor : public clang::RecursiveASTVisitor<PrintfCheckVisitor> { class impl; std::unique_ptr<impl> pimpl; public: PrintfCheckVisitor (clang::ASTContext *ctx, clang::CompilerInstance &ci); virtual ~PrintfCheckVisitor (void); bool VisitCallExpr (clang::CallExpr *E); };
äž»ãªã¢ã€ãã¢ã¯ã
clang::RecursiveASTVisitor
ããã®ç¶æ¿ã§ãããããªãŒãèµ°æ»ããé¢æ°åŒã³åºããããªãŒå
ã«ãããšãã«åŒã³åºããã
VisitCallExpr
ã¡ãœããã®å®çŸ©ã§ãã ãã®ã¡ãœããïŒpimplã§ãããã·ãããŸãïŒã§ã¯ãé¢æ°ãšãã®åŒæ°ã®è§£æã«é¢ããäž»ãªäœæ¥ãè¡ãããŸãã ã¡ãœããã¯æ¬¡ã®ããã«å§ãŸããŸãã
bool VisitCallExpr (CallExpr *E) { auto callee = dyn_cast<NamedDecl> (E->getCalleeDecl ()); if (callee == NULL) { llvm::errs () << "Bad callee\n"; return false; } auto fname = callee->getNameAsString (); auto pos_it = printf_functions.find (fname); if (pos_it != printf_functions.end ()) {
ãã®ã³ãŒãã§ã¯ãåŒããé¢æ°ã®å®çŸ©ïŒå®£èšïŒãååŸããé¢æ°ã®ååãæœåºããŸãã 次ã«ããã®é¢æ°ã«èå³ããããã©ãã
printf_functions
ããã·ã¥ã調ã¹ãŸãã
printf_functions = { {"rspamd_printf", 0}, {"rspamd_default_log_function", 4}, {"rspamd_snprintf", 2}, {"rspamd_fprintf", 1} };
æ°å€ã¯ãåŒæ°å
ã®ã¯ãšãªæååã®äœçœ®ã瀺ããŸãã ããã«ãé¢æ°ã«èå³ãããå Žåã¯ãã¯ãšãªæååãæœåºããŠåæããŸãïŒãã®ããã«ããã®èšäºã®ç¯å²å€ã®ãªãŒãããã³ãäœæããŸããïŒã
const auto args = E->getArgs (); auto pos = pos_it->second; auto query = args[pos]; if (!query->isEvaluatable (*pcontext)) { print_warning (std::string ("cannot evaluate query"), E, this->pcontext, this->ci); return false; } clang::Expr::EvalResult r; if (!query->EvaluateAsRValue (r, *pcontext)) { print_warning (std::string ("cannot evaluate rvalue of query"), E, this->pcontext, this->ci); return false; } auto qval = dyn_cast<StringLiteral> ( r.Val.getLValueBase ().get<const Expr *> ()); if (!qval) { print_warning (std::string ("bad or absent query string"), E, this->pcontext, this->ci); return false; }
ãã®ã¹ããããã§éèŠãªã®ã¯ãå¯èœã§ããã°æå
ã«ã¯ãšãªæååã
èšç®ããããš
ããããšã§ãã ããã¯ãããšãã°ãã¯ãšãªæååãä»»æã®åŒã䜿çšããŠåœ¢æãããŠããå Žåã«äŸ¿å©ã§ãã æ®å¿µãªãããlibclangã§å€ãæäœããããšã¯éåžžã«å°é£ã§ããåŒãååŸãããããè©äŸ¡ïŒEvaluateAsRValueïŒããLValueã«å€æå¯èœãªçµæãââååŸããŠããStringLiteralã«å€æããå¿
èŠããããŸãã èšç®ãäžèŠãªå Žåã¯ã
Expr *
çŽæ¥äœ¿çšããŠ
StringLiteral
ã«
Expr *
ãããšãã³ãŒãã倧å¹
ã«ç°¡çŽ åãããŸãã
次ã«ãã¯ãšãªæååãåæãããã®ãããªæ§é ã®ãã¯ãã«ãååŸããŸããã
struct PrintfArgChecker { private: arg_parser_t parser; public: int width; int precision; bool is_unsigned; ASTContext *past; CompilerInstance *pci; PrintfArgChecker (arg_parser_t _p, ASTContext *_ast, CompilerInstance *_ci) : parser (_p), past (_ast), pci(_ci) { width = 0; precision = 0; is_unsigned = false; } virtual ~PrintfArgChecker () { } bool operator() (const Expr *e) { return parser (e, this); } };
ãã®ãããªåæ§é ã«ã¯ãåŒæ°ïŒ
Expr *
ïŒãåããæå®ããããã®ã«æºæ ããŠãããã©ããã¿ã€ãããã§ãã¯ããåŒã³åºãã¡ãœãããå«ãŸããŠããŸãã 次ã«ãã¯ãšãªæååã®åŸã®ãã¹ãŠã®åŒæ°ã§åã®äžèŽã確èªããŸãã
if (parsers->size () != E->getNumArgs () - (pos + 1)) { std::ostringstream err_buf; err_buf << "number of arguments for " << fname << " missmatches query string '" << qval->getString ().str () << "', expected " << parsers->size () << " args" << ", got " << (E->getNumArgs () - (pos + 1)) << " args"; print_error (err_buf.str (), E, this->pcontext, this->ci); return false; } else { for (auto i = pos + 1; i < E->getNumArgs (); i++) { auto arg = args[i]; if (arg) { if (!parsers->at (i - (pos + 1)) (arg)) { return false; } } } }
print_error
é¢æ°
print_error
ãã³ã³ãã€ã«ãšã©ãŒãåºåããã³ã³ãã€ã«ããã»ã¹ãåæ¢ã§ãããšããç¹ã§èå³æ·±ãã§ãã ããã¯
CompilerInstance
ãä»ããŠè¡ãããŸãããããªãæçœã§ã¯ãããŸããïŒ
static void print_error (const std::string &err, const Expr *e, const ASTContext *ast, CompilerInstance *ci) { auto loc = e->getExprLoc (); auto &diag = ci->getDiagnostics (); auto id = diag.getCustomDiagID (DiagnosticsEngine::Error, "format query error: %0"); diag.Report (loc, id) << err; }
ãããã£ãŠãèŠåã衚瀺ããã«ã¯ã
DiagnosticsEngine::Warning
䜿çšããå¿
èŠããããŸãã
äžè¬çã«ãååæã¯2ã€ã®æ¹æ³ã§å®è¡ãããŸãã 1ã€ã¯çµã¿èŸŒã¿åïŒããšãã°long / intãªã©ïŒããã§ãã¯ã§ãã2çªç®ã¯è€éãªåïŒããšãã°æ§é äœïŒããã§ãã¯ã§ããŸãã åçŽåã確èªããã«ã¯ã
clang::BuiltinType::Kind
䜿çšããŸããããã¯ãã¯ã©ã³ã«æ¢ç¥ã®ãã¹ãŠã®åãå®çŸ©ããŸãã å¯èœãªå€ã¯
/usr/include/clang/AST/BuiltinTypes.def
å ŽåïŒã«ãããŸãã 埮åŠãªç¹ã2ã€ãããŸãã
- åºå®ãµã€ãºã®intã¯çµã¿èŸŒã¿åãšç°ãªãæ¹æ³ã§äžèŽããå¯èœæ§ãããããã
if (sizeof (int32_t) == sizeof (int)) {...} if (sizeof (int32_t) == sizeof (long)) {...}
ãããªãã§ãã¯ãè¡ãå¿
èŠããããŸãif (sizeof (int32_t) == sizeof (int)) {...} if (sizeof (int32_t) == sizeof (long)) {...}
- åŒæ°ã¯ä»ã®åã®ãšã€ãªã¢ã¹ã«ãªãå¯èœæ§ããããããæåã«ãããã®ãšã€ãªã¢ã¹ãåãé€ãå¿
èŠããããŸããããšãã°ã
typedef my_int int
åçŽåããã§ãã¯ããããã®æåŸã®é¢æ°ã¯æ¬¡ã®ããã«ãªããŸãã
static bool check_builtin_type (const Expr *arg, struct PrintfArgChecker *ctx, const std::vector <BuiltinType::Kind> &k, const std::string &fmt) { auto type = arg->getType ().split ().Ty; auto desugared_type = type->getUnqualifiedDesugaredType (); if (!desugared_type->isBuiltinType ()) { print_error ( std::string ("not a builtin type for ") + fmt + " arg: " + arg->getType ().getAsString (), arg, ctx->past, ctx->pci); return false; } auto builtin_type = dyn_cast<BuiltinType> (desugared_type); auto kind = builtin_type->getKind (); auto found = false; for (auto kk : k) { if (kind == kk) { found = true; break; } } if (!found) { print_error ( std::string ("bad argument for ") + fmt + " arg: " + arg->getType ().getAsString () + ", resolved as: " + builtin_type->getNameAsCString (ctx->past->getPrintingPolicy ()), arg, ctx->past, ctx->pci); return false; } return true; }
ã芧ã®ãšããã
getUnqualifiedDesugaredType
ã¡ãœããã䜿çšããŠãšã€ãªã¢ã¹ãåé€ãã
arg->getType()
䜿çšããŠåŒããåŒã®åãååŸããŸãã ãã ãããã®ã¡ãœããã¯ããã®ã¿ã¹ã¯ã«å¿
èŠã§ã¯ãªã修食åïŒããšãã°ã
const
æå®åãå«ãïŒãè¿ãããã修食åã¯
split
ã«ãªããçµæã®æ§é ããçŽç²ãªåã®ã¿ãååŸãããŸãã
è€ååã®å Žåãæ§é äœãåæããŸãã¯ãŠããªã³ã®ååã匷調衚瀺ããå¿
èŠããããŸãã ãã§ãã¯æ©èœã¯æ¬¡ã®ããã«ãªããŸãã
static bool check_struct_type (const Expr *arg, struct PrintfArgChecker *ctx, const std::string &sname, const std::string &fmt) { auto type = arg->getType ().split ().Ty; if (!type->isPointerType ()) { print_error ( std::string ("bad string argument for %s: ") + arg->getType ().getAsString (), arg, ctx->past, ctx->pci); return false; } auto ptr_type = type->getPointeeType ().split ().Ty; auto desugared_type = ptr_type->getUnqualifiedDesugaredType (); if (!desugared_type->isRecordType ()) { print_error ( std::string ("not a record type for ") + fmt + " arg: " + arg->getType ().getAsString (), arg, ctx->past, ctx->pci); return false; } auto struct_type = desugared_type->getAsStructureType (); auto struct_decl = struct_type->getDecl (); auto struct_def = struct_decl->getNameAsString (); if (struct_def != sname) { print_error (std::string ("bad argument '") + struct_def + "' for " + fmt + " arg: " + arg->getType ().getAsString (), arg, ctx->past, ctx->pci); return false; } return true; }
åŒæ°ã¯æ§é äœã§ã¯ãªãããã®ãã€ã³ã¿ãŒã§ãããšæ³å®ããŠããããããŸã
type->getPointeeType().split().Ty
䜿çšããŠãã€ã³ã¿ãŒã®åã決å®ããŸãã 次ã«ããã·ã¥ã¬ãŒãå®è¡ããã¿ã€ãã®å®£èšãèŠã€ããŸãïŒ
struct_type->getDecl()
ã ãã®åŸããã§ãã¯ã¯ããªãç°¡åãªæ¹æ³ã§è¡ãããŸãã
çµæ
ãã¡ããããã©ã°ã€ã³ãäœæããåŸãã¡ã€ã³ã³ãŒãã§ã©ã®ããã«æ©èœãããã確èªãå§ããŸããã åã«ã¯ç°¡åãªåé¡ããããŸããïŒ
[44ïŒ
] Cãªããžã§ã¯ãã®äœæsrc / CMakeFiles / rspamd-server.dir / libutil / map.co
src / libutil / map.cïŒ906ïŒ46ïŒãšã©ãŒïŒformat query errorïŒbad argument forïŒ
z argïŒguintã解決æžã¿ïŒunsigned int
msg_info_poolïŒ "ïŒ
zèŠçŽ ã®ããã·ã¥ãèªã¿åã"ãg_hash_table_size
^
src / libutil / logger.hïŒ190ïŒ9ïŒæ³šïŒãã¯ããmsg_info_poolãããå±é
__VA_ARGS__ïŒ
^
1ãšã©ãŒãçæãããŸããã
æ·±å»ãªåé¡ããããŸãã
[45ïŒ
] Cãªããžã§ã¯ãã®äœæsrc / CMakeFiles / rspamd-server.dir / libserver / protocol.co
src / libserver / protocol.cïŒ373ïŒ45ïŒãšã©ãŒïŒã¯ãšãªã®ãã©ãŒããããšã©ãŒïŒïŒ
Vã®äžæ£ãªåŒæ° 'f_str_tok' argïŒrspamd_ftok_t *
msg_err_taskïŒãããããŒããã®äžæ£ïŒ 'ïŒ
V'ããh->å€ïŒ;
^
src / libutil / logger.hïŒ164ïŒ9ïŒæ³šïŒãã¯ããmsg_err_taskãããå±é
__VA_ARGS__ïŒ
^
1ãšã©ãŒãçæãããŸããã
[44ïŒ
] Cãªããžã§ã¯ãã®äœæsrc / CMakeFiles / rspamd-server.dir / libstat / tokenizers / osb.co
src / libstat / tokenizers / osb.cïŒ128ïŒ48ïŒãšã©ãŒïŒformat query errorïŒbad string argument forïŒ
sïŒgsize
msg_warnïŒ "siphashããŒãçãããŸãïŒïŒ
s"ãkeylenïŒ;
^
src / libutil / logger.hïŒ145ïŒ9ïŒæ³šïŒãã¯ããmsg_warnãããå±é
__VA_ARGS__ïŒ
^
1ãšã©ãŒãçæãããŸããã
åŒæ°ã®æ°ã«é¢ããåé¡ïŒ
[46ïŒ
] Cãªããžã§ã¯ãã®äœæsrc / CMakeFiles / rspamd-server.dir / libmime / mime_expressions.co
src / libmime / mime_expressions.cïŒ780ïŒ3ïŒerrorïŒformat query errorïŒnumber of arguments for rspamd_default_log_function missmatches query string
ãurlïŒ
sã®ããã»ã¹ãã¹ãregexpïŒ
sãFALSEãè¿ããŸãããã2ã€ã®åŒæ°ãå¿
èŠã§ã1ã€ã®åŒæ°ãååŸ
msg_info_taskïŒ "urlïŒ
sã®ããã»ã¹ãã¹ãregexpïŒ
sã¯FALSEãè¿ããŸãã"ã
^
src / libutil / logger.hïŒ169ïŒ30ïŒæ³šïŒãã¯ããmsg_info_taskãããå±é
#define msg_info_taskïŒ...ïŒrspamd_default_log_functionïŒG_LOG_LEVEL_INFOã\
^
1ãšã©ãŒãçæãããŸããã
ãã©ãŒãããã¯ãšãªã§åèš47ã®åé¡ãèŠã€ãããŸããã次ã®ã³ãããã§ç¢ºèªã§ããŸãïŒ
http :
//git.io/v8Nyvãã©ã°ã€ã³ã³ãŒãã¯
ãã¡ãããå
¥æã§ã
ãŸã ã