ã¯ããã«
åæã®ããã«ãææ°ã®ãœãŒã¹ã¯äž»èŠãªãªããžããªïŒ Ruby ã Python ïŒããååŸãããŸããã æ€èšŒã¯ã PVS-StudioããŒãžã§ã³6.06éçã³ãŒãã¢ãã©ã€ã¶ãŒã䜿çšããŠå®è¡ãããŸããã Pythonã¯Visual Studioã§é©åã«æ§ç¯ãããŠãããRubyã®å Žåã¯ãã³ã³ãã€ã©ãŒåŒã³åºãã®ç£èŠã¢ãŒãã§ã¹ã¿ã³ãã¢ãã³ããŒãžã§ã³ã䜿çšã§ããŸãã
ãããžã§ã¯ãã«ã¯ããã»ã©å€ãã®é²éªšãªãšã©ãŒã¯ãããŸããã§ãããè¯å®çãªãã®ã®ã»ãšãã©ã¯ãã¯ãã®äœ¿çšã«é¢ä¿ããŠããããã¯ãã¯ã¢ãã©ã€ã¶ãŒã®èŠ³ç¹ããã¯éåžžã«çãããã³ãŒãã§é瀺ãããŠããŸãããéçºè ã®èŠ³ç¹ããã¯ç¡å®³ã§ãã ãã¯ããæªã§ãããã©ããã«ã€ããŠé·ãéè°è«ã§ããŸãããã¢ãã©ã€ã¶ãŒããã¯ãã奜ãŸãªãããšã¯ç¢ºãã§ãã è¿·æãªãã¯ããåãé€ãããã«ã誀æ€ç¥ãæå¶ãããªãã·ã§ã³ããããŸãã æžãã ãã§ååã§ãïŒ
//-V:RB_TYPE_P:501
ãããŠãRB_TYPE_Pãã¯ããããªã¬ãŒãããã¹ãŠã®V501蚺æãæ¶ããŸãã
Python
ãã©ã°ã¡ã³ãN1
#ifdef MS_WINDOWS typedef SOCKET SOCKET_T; #else typedef int SOCKET_T; #endif typedef struct { PyObject_HEAD SOCKET_T sock_fd; /* Socket file descriptor */ .... } PySocketSockObject; static int internal_select(PySocketSockObject *s, int writing, _PyTime_t interval, int connect) { .... if (s->sock_fd < 0) // <= return 0; .... }
V547åŒ 's-> sock_fd <0'ã¯åžžã«falseã§ãã 笊å·ãªãã®åã®å€ã<0ã«ãªãããšã¯ãããŸããsocketmodule.c 655
Windowsã®SOCKETã¿ã€ãã¯ç¬Šå·ãªããªã®ã§ããŒããšæ¯èŒããŠãæå³ããããŸããã socketïŒïŒé¢æ°ãæå¹ãªèšè¿°åãè¿ãããã©ããã確èªããã«ã¯ããã®å€ãINVALID_SOCKETãšæ¯èŒããå¿ èŠããããŸãã Linuxã§ã¯ããœã±ããã¿ã€ããšããŠç¬Šå·ä»ãintã䜿çšããã-1ã®å€ããšã©ãŒãéç¥ããããããã®æ¯èŒãæ£ããæ©èœããããšã«æ³šæããŠãã ããã ãã ããæ€èšŒã«ã¯ç¹å¥ãªãã¯ããŸãã¯å®æ°ã䜿çšããããšããå§ãããŸãã
èŠåãçºè¡ãããåæ§ã®ãã§ãã¯ïŒ
- V547åŒ 's-> sock_fd <0'ã¯åžžã«falseã§ãã 笊å·ãªãã®åã®å€ã<0ã«ãªãããšã¯ãããŸããã_ssl.c1702
- V547åŒ 'sock-> sock_fd <0'ã¯åžžã«falseã§ãã 笊å·ãªãã®åã®å€ã<0ã«ãªãããšã¯ãããŸããã_ssl.c2018
ãã©ã°ã¡ã³ãN2
int ASN1_PRINTABLE_type(const unsigned char *s, int len) { int c; int ia5 = 0; .... if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == ' ') || // <= ((c >= '0') && (c <= '9')) || (c == ' ') || (c == '\'') || // <= (c == '(') || (c == ')') || (c == '+') || (c == ',') || (c == '-') || (c == '.') || (c == '/') || (c == ':') || (c == '=') || (c == '?'))) ia5 = 1; .... }
V501 ã||ãã®å·Šãšå³ã«åäžã®å¯æ¬¡åŒãïŒc ==ããïŒãããããŸã æŒç®åã a_print.c 77
Copy-Pasteã®çµæãšããŠçºçãããšã©ãŒã®å žåçãªäŸã å€ãã®å Žåãã³ããŒããããããã¯ãå€æ°ãããšãããã°ã©ããŒã¯æ³šæã倱ãããã®ãã¡ã®1ã€ã®å€æ°ãŸãã¯å®æ°ãå€æŽããã®ãå¿ããŸãã ãããã£ãŠããã®å Žåã倧ããªæ¡ä»¶åŒã§ã¯ãå€æ°cãšæ¯èŒãããå€ãæ··åãããŸãã æ£ç¢ºã«èšãããšã¯äžå¯èœã§ãããäºéåŒçšç¬Š '' 'ãå¿ããããã§ãã
ãã©ã°ã¡ã³ãN3
static PyObject * semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) { .... HANDLE handles[2], sigint_event; .... /* prepare list of handles */ nhandles = 0; handles[nhandles++] = self->handle; if (_PyOS_IsMainThread()) { sigint_event = _PyOS_SigintEvent(); assert(sigint_event != NULL); handles[nhandles++] = sigint_event; } /* do the wait */ Py_BEGIN_ALLOW_THREADS if (sigint_event != NULL) //<= ResetEvent(sigint_event); .... }
V614æœåšçã«åæåãããŠããªããã€ã³ã¿ãŒ 'sigint_event'ã䜿çšãããŸããã semaphore.c 120
_PyOS_IsMainThreadïŒïŒé¢æ°ãfalseãè¿ãå Žåã sigint_eventãã€ã³ã¿ãŒã¯åæåãããªããŸãŸã«ãªããŸãã ããã«ãããæªå®çŸ©ã®åäœãçºçããŸãã ãã®ãããªãšã©ãŒã¯ããããã°ããŒãžã§ã³ã§ã¯ç°¡åã«èŠèœãšãããå¯èœæ§ããããŸãããããã°ããŒãžã§ã³ã§ã¯ããã€ã³ã¿ãŒã¯ã»ãšãã©ã®å ŽåãŒãã«åæåãããŸãã
ãã©ã°ã¡ã³ãN4
#define BN_MASK2 (0xffffffffffffffffLL) int BN_mask_bits(BIGNUM *a, int n) { .... a->d[w] &= ~(BN_MASK2 << b); //<= .... }
V610æªå®çŸ©ã®åäœã ã·ããæŒç®åã<<ãã確èªããŠãã ããã å·Šã®ãªãã©ã³ã 'ïŒ0xffffffffffffffffffLLïŒ'ã¯è² ã§ãã bn_lib.c 796
ã»ãšãã©ã®å Žåãã³ãŒãã¯æ©èœããŸããããã®åŒã¯æšæºã§ã¯æªå®çŸ©ã®åäœã§ãã Andrei Karpovã®èšäºã§ãè² ã®æ°ã®ã·ããã«ã€ããŠè©³ããèªãããšãã§ããŸããã ãã©ãŒããç¥ããªãã§ãæ°Žã«å ¥ããªãã§ãã ãããããŒã3 ãã çµæãèŠæ Œã§ä¿èšŒãããŠããªãèšèšãåé¿ãã䟡å€ããããã©ããã¯ããªã次第ã§ããããããæåŠããæ¹ãè¯ããšã¢ãã©ã€ã¶ãŒã¯èŠåããŠããŸãã
static PyObject * binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header) { Py_ssize_t in, out; const unsigned char *databuf; .... if ((databuf[in] > 126) || (databuf[in] == '=') || (header && databuf[in] == '_') || ((databuf[in] == '.') && (linelen == 0) && (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) || (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || ((databuf[in] < 33) && (databuf[in] != '\r') && (databuf[in] != '\n') && (quotetabs || (!quotetabs && ((databuf[in] != '\t') && // <= (databuf[in] != ' ')))))) { .... } .... }
V728éå°ãªãã§ãã¯ãç°¡çŽ åã§ããŸãã ã||ã æŒç®åã¯ãå察ã®åŒãquotetabsããšãïŒquotetabsãã«å²ãŸããŠããŸãã binascii.c 1453
ãã®ãã©ã°ã¡ã³ãã¯èª€ãã§ã¯ãããŸããããåå¥ã«æ€èšãã䟡å€ããããŸãã èŠåã¯äž»ã«å©èšçã§ãïŒ 'A ||圢åŒã®è¡šçŸ ïŒïŒA && BïŒ 'A ||ã«ç°¡ç¥åã§ããŸãã B ' ïŒããã«ãããå°ãæŽç·Žãããã³ãŒããå°ãç°¡åã«èªãããšãã§ããŸãã
åæ§ã®èŠåïŒ
- V728éå°ãªãã§ãã¯ãç°¡çŽ åã§ããŸãã ã||ã æŒç®åã¯ãå察ã®åŒãïŒtypeããšãtypeãã«å²ãŸããŠããŸãã digest.c 167
- V728éå°ãªãã§ãã¯ãç°¡çŽ åã§ããŸãã ã||ã æŒç®åã¯ãå察ã®è¡šçŸãïŒcipherããšãcipherãã«å²ãŸããŠããŸãã evp_enc.c 120
ãã©ã°ã¡ã³ãN5
static int dh_cms_set_peerkey(....) { .... int atype; .... /* Only absent parameters allowed in RFC XXXX */ if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) goto err; .... }
V590 ãatypeïŒ=-1 && atype == 5ãåŒã®æ€æ»ãæ€èšããŠãã ããã è¡šçŸãéå°ã§ãããã誀æ€ãå«ãŸããŠããŸãã dh_ameth.c 670
å¥åŠãªããšã«ãè«çåŒã®ãšã©ãŒã¯ã倧èŠæš¡ãªãããžã§ã¯ãã§ãéåžžã«äžè¬çã§ãã ãã®ãã©ã°ã¡ã³ãã®è«çåŒã¯åé·ã§ããã atype == V_ASN1_NULL ãã«ç°¡ç¥åã§ããŸãã ã»ãšãã©ã®å Žåãã³ã³ããã¹ãã«åºã¥ããŠãããã«ãšã©ãŒã¯ãããŸãããããã®ãããªã³ãŒãã¯çãããããã«èŠããŸãã
ãã©ã°ã¡ã³ãN6
static void cms_env_set_version(CMS_EnvelopedData *env) { .... if (env->originatorInfo || env->unprotectedAttrs) env->version = 2; env->version = 0; }
V519 ã env- > versionãå€æ°ã«ã¯ãé£ç¶ããŠ2åå€ãå²ãåœãŠãããŸãã ããããããã¯ééãã§ãã è¡ã確èªããŠãã ããïŒ907ã908ãcms_env.c 908
ãã®ã³ãŒãã®äœæè ãå ã æ瀺ããŠãããã®ãèšãã®ã¯å°é£ã§ãã ãããããããã«ä»ã®è¡æ¹äžæããããŸãã ifã«ã¯æå³ããããŸãããå€æ° ' env-> version'ã®å€ã¯ã©ã®å Žåã§ãäžæžããããããã§ãã
ãã©ã°ã¡ã³ãN7
int _PyState_AddModule(PyObject* module, struct PyModuleDef* def) { PyInterpreterState *state; if (def->m_slots) { PyErr_SetString(PyExc_SystemError, "PyState_AddModule called on module with slots"); return -1; } state = GET_INTERP_STATE(); if (!def) return -1; .... }
V595 nullptrã«å¯ŸããŠæ€èšŒãããåã«ãã self- > extraããã€ã³ã¿ãŒã䜿çšãããŸããã è¡ã確èªããŠãã ããïŒ917ã923ã_elementtree.c 917
ã»ãšãã©ãã¹ãŠã®ãããžã§ã¯ãã§çºçãããã«ãã€ã³ã¿ãŒã®éåç §ã«é¢é£ããåŸæ¥ã®ãšã©ãŒã æåã«ãåŒ'def-> m_slots'ã§ããããã¯ããã¢ãã¬ã¹ãåç §ãã次ã«ãã®ã¢ãã¬ã¹ããŒãã§ããããšãå€æããŸããã çµæãšããŠãnullãã€ã³ã¿ãŒã®éåç §ãçºçããããã°ã©ã ã®ã¯ã©ãã·ã¥ãªã©ã®æªå®çŸ©ã®åäœã«ã€ãªããããã nullptrã®ãã§ãã¯ã¯æ©èœããŸããã
ã«ããŒ
ãã©ã°ã¡ã³ãN1
static void vm_set_main_stack(rb_thread_t *th, const rb_iseq_t *iseq) { VALUE toplevel_binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")); rb_binding_t *bind; rb_env_t *env; GetBindingPtr(toplevel_binding, bind); GetEnvPtr(bind->env, env); vm_set_eval_stack(th, iseq, 0, &env->block); /* save binding */ if (bind && iseq->body->local_size > 0) { bind->env = vm_make_env_object(th, th->cfp); } }
V595 nullptrã«å¯ŸããŠæ€èšŒãããåã«ãããã€ã³ãããã€ã³ã¿ãŒã䜿çšãããŸããã è¡ã確èªïŒ377ã382ãvm.c 377
Rubyãããžã§ã¯ãã§åæ§ã®ãšã©ãŒãåé¿ããŸããã§ããã ãifïŒbindïŒãããã§ãã¯ããŠããäžèšã®ã³ãŒãã§ãã€ã³ããéåç §ãããŠããããããã©ãã«ããããªããæãããšã¯ãããŸããã Rubyã«ã¯30ãè¶ ãããã®ãããªèŠåããããŸããããããããã¹ãŠãèŠåããæå³ã¯ãããŸããã
ãã©ã°ã¡ã³ãN2
static int code_page_i(....) { table = realloc(table, count * sizeof(*table)); if (!table) return ST_CONTINUE; .... }
V701 reallocïŒïŒãªãŒã¯ã®å¯èœæ§ïŒreallocïŒïŒãã¡ã¢ãªã®å²ãåœãŠã«å€±æãããšãå ã®ãã€ã³ã¿ 'table'ã倱ãããŸãã reallocïŒïŒãäžæãã€ã³ã¿ãŒã«å²ãåœãŠãããšãæ€èšããŠãã ããã file.c 169
ã³ãŒãã®ãã®ã»ã¯ã·ã§ã³ã§ã¯ãreallocå€ã¯åŒæ°ãšããŠäœ¿çšãããã®ãšåãå€æ°ã«æ ŒçŽãããŸãã reallocãnullptrãè¿ãå Žåããã€ã³ã¿ã®å ã®å€ã¯å€±ãããã¡ã¢ãªãªãŒã¯ãçºçããŸãã
ãã©ã°ã¡ã³ãN3
static int w32_symlink(UINT cp, const char *src, const char *link) { .... BOOLEAN ret; typedef DWORD (WINAPI *create_symbolic_link_func) (WCHAR*, WCHAR*, DWORD); static create_symbolic_link_func create_symbolic_link = (create_symbolic_link_func)-1; .... ret = create_symbolic_link(wlink, wsrc, flag); ALLOCV_END(buf); if (!ret) { int e = GetLastError(); errno = map_errno(e); return -1; } return 0; }
V724ã¿ã€ããDWORDããã¿ã€ããBOOLEANãã«å€æãããšãé«äœãããã倱ãããå¯èœæ§ããããŸãã ãŒã以å€ã®å€ã¯ãFALSEãã«ãªãå¯èœæ§ããããŸãã win32.c 4974
BOOLEANåã¯ãWinAPIã§è«çåãšããŠäœ¿çšãããŸãã 次ã®ããã«å®£èšãããŸãã
typedef unsigned char BYTE; typedef BYTE BOOLEAN;
DWORDã¯32ãããã®ç¬Šå·ãªãæ°å€ã§ãã ãããã£ãŠãããšãã°ãDWORDå€0xffffff00ãBOOLEANïŒãŸãã¯æäžäœãããããŒãã«çããä»ã®å€ïŒã«èšå®ãããšã0ãã€ãŸãFALSEã«ãªããŸãã
ãã©ã°ã¡ã³ãN4
static VALUE rb_str_split_m(int argc, VALUE *argv, VALUE str) { .... char *ptr = RSTRING_PTR(str); long len = RSTRING_LEN(str); long start = beg; .... if (ptr+start == ptr+len) start++; .... }
V584 ã==ãæŒç®åã®äž¡åŽã«ãptrãå€ããããŸãã åŒãæ£ãããªãããåçŽåã§ããŸãã string.c 7211
æ¯èŒã®äž¡æ¹ã®éšåã§ã ptrã®è¿œå ãååšãããããçç¥ã§ããŸãã
if (start == len)
ã»ãšãã©ã®å Žåããã®ãã©ã°ã¡ã³ãã«ã¯ãšã©ãŒã¯ãããŸããã ãã ãããã®ãããªåŒã§ã¯ãå€ãã®å Žåã2ã€ã®ç°ãªãå€æ°ãå®éã«æ¯èŒããããšèããŠããŸãã ãããã£ãŠããã®ãããªæ¯èŒã«æ³šæããããšããå§ãããŸãã
ãŸãšã
æ±çšèšºæã«ãã£ãŠçºè¡ããããã¹ãŠã®èŠåãåæãããã¹ãŠã®èª€æ€ç¥ãåé€ããåŸã次ã®ãšã©ãŒååžã«å°éããŸããã
Rubyã®ããªã¬ãŒã®ã»ãšãã©ã¯V610èŠåïŒ369åã®ããªããïŒïŒããçºçããŸããããããããé€å€ããŠãç¶æ³ã¯å€ãããŸãããPythonã§ã¯ãçãããã¹ãããã®æ°ã¯ãŸã å°ãªãã§ãã
V595蚺æã¯æãé »ç¹ã«è¡ãããããšãå€æããŸãããPythonã³ãŒãã§ã¯ 17åãRubyã³ãŒãã§ã¯37åçºçããŸãã ã
ããããæãèå³æ·±ãã®ã¯ãšã©ãŒå¯åºŠæ¯ã§ãã ãã®ç¹æ§ã«ãããPythonãåªããŠããŸãã èšç®çµæã¯æ¬¡ã®è¡šã«èšèŒãããŠããŸãã
ããã¯å€ãã®ééãã®ããã«èŠãããããããŸããã ããã§ã¯ãããŸããã ãŸããèŠã€ãã£ããšã©ãŒã®ãã¹ãŠãéèŠãªããã§ã¯ãããŸããã ããšãã°ãåè¿°ã®V610蚺æã¯ãC ++èšèªã®èŠ³ç¹ãããšã©ãŒãæ€åºããŸãã ãã ããå®éã«ã¯ã䜿çšãããã³ã³ãã€ã©ã®ã»ããã«å¯ŸããŠçµæãåžžã«æ£ããå ŽåããããŸãã ãã®ãšã©ãŒã¯ãšã©ãŒã§ã¯ãªããªããŸããããçŸåšããã°ã©ã ã«åœ±é¿ã¯ãããŸããã 第äºã«ããã§ãã¯ãããã³ãŒãã®ãµã€ãºãèæ ®ããå¿ èŠããããŸãã ãããã£ãŠããããã®ãããžã§ã¯ãã®é«å質ã«ã€ããŠè©±ãããšãã§ããŸãã ãããŸã§ã¯ããã¹ãæžã¿ãããžã§ã¯ãã®ãšã©ãŒå¯åºŠãèšç®ããŠããªãã£ãããããã®è©äŸ¡ã¯äž»èŠ³çã§ãã ãã ããåŸã§æ¯èŒã§ããããã«ãå°æ¥çã«ã¯ãããå®è¡ããããšããŸãã
ãããã«
Pythonããã³Rubyèšèªã¯éåžžã«äººæ°ããããäžçäžã®äœçŸäžäººãã®éçºè ã«ãã£ãŠæžãããŠããŸãã ãã®ãããªãããžã§ã¯ãããã³ã³ãã¥ããã£ã®æŽ»åãã³ãŒãã®è³ªã®é«ããåªãããã¹ããããã³éçåæã®äœ¿çšïŒäž¡æ¹ã®ãããžã§ã¯ãã¯Coverityã䜿çšããŠãã§ãã¯ãããŸãïŒã§ã¯ãå€æ°ã®ãšã©ãŒãèŠã€ããããšã¯å°é£ã§ãã ããã«ãããããããPVS-Studioã¯ããã€ãã®äžå¯©ãªå ŽæãèŠã€ããããšãã§ããŸããã ããããã³ãŒããå®æçã«ãã§ãã¯ããããšã§ãéçºè ã®ç掻ãå€§å¹ ã«æ¥œã«ãªãããšãç解ãã䟡å€ããããŸãã å€æŽããªããžããªã«åæ ãããŠãªãªãŒã¹ãããçŽåã«ãšã©ãŒãä¿®æ£ããã®ãæåã§ã-éçã¢ãã©ã€ã¶ãŒã¯ããããä»ã«é¡ãã¿ãã«è¡ãã®ã«åœ¹ç«ã¡ãŸã
誰ããèªåã®ãããžã§ã¯ãã§PVS-Studioãè©Šãããšããå§ãããŸãã
ãã®èšäºãè±èªã話ãèŽè¡ãšå ±æãããå Žåã¯ã翻蚳ãžã®ãªã³ã¯ã䜿çšããŠãã ããïŒPavel Belikovã PythonãšRubyã®å®è£ ããšã©ãŒå¯åºŠã§æ¯èŒããŸãã ã
èšäºãèªãã§è³ªåããããŸããïŒ
å€ãã®å Žåãèšäºã«ã¯åã質åãå¯ããããŸãã ããã§åçãéããŸããïŒ PVS-StudioããŒãžã§ã³2015ã«é¢ããèšäºã®èªè
ããã®è³ªåãžã®åç ã ãªã¹ããã芧ãã ããã
æŽæ°ãã ãã®èšäºã«ã¯äžæ£ç¢ºãªå 容ãå«ãŸããŠããŸãã CPythonãšRubyãããžã§ã¯ãæ€èšŒã®èª¬æãã芧ãã ããã