|
下面的代码(当然包括错误,以检验splint的功能):#includeintmain(intargc,char*argv[]){inta=100。 /*没有使用的变量*/intb[8]。 /*明显数组越界*//*用到了两个为声明的变量c和d/c=100! }现在可以用splint来检查一下,为了检验是否可以检测到数组越界,使用+bounds选项; splinthi.c+bounds输出结果:hi.c:(infunctionmain)hi.c:9:2:Unrecognizedidentifier:cIdentifierusedincodehasnotbeendeclared.(Use-unrecogtoinhibitwarning)hi.c:10:2:Unrecognizedidentifier:dhi.c:4:6:VariableadeclaredbutnotusedAvariableisdeclaredbutneverused.Use/*@unused@*/infrontofdeclarationtosuppressmessage.(Use-varusetoinhibitwarning)hi.c:7:2:Likelyout-of-boundsstore:b[9]Unabletoresolveconstraint:requires7>=9neededtosatisfyprecondition:requiresmaxSet(b@hi.c:7:2)>=9Amemorywritemaywritetoanaddressbeyondtheallocatedbuffer.(Use-likely-boundswritetoinhibitwarning)hi.c:3:14:ParameterargcnotusedAfunctionparameterisnotusedinthebodyofthefunction.Iftheargumentisneededfortypecompatibilityorfutureplans,use/*@unused@*/intheargumentdeclaration.(Use-paramusetoinhibitwarning)hi.c:3:25:ParameterargvnotusedFinishedchecking---6codewarnings现在详细看一下结果:检查结果1:hi.c:9:2:Unrecognizedidentifier:cIdentifierusedincodehasnotbeendeclared.(Use-unrecogtoinhibitwarning)hi.c:10:2:Unrecognizedidentifier:dhi.c:4:6:VariableadeclaredbutnotusedAvariableisdeclaredbutneverused.Use/*@unused@*/infrontofdeclarationtosuppressmessage.(Use-varusetoinhibitwarning)这些应该是splint检测到变量c和d没有声明; 检查结果2:hi.c:7:2:Likelyout-of-boundsstore:b[9]Unabletoresolveconstraint:requires7>=9neededtosatisfyprecondition:requiresmaxSet(b@hi.c:7:2)>=9Amemorywritemaywritetoanaddressbeyondtheallocatedbuffer.(Use-likely-boundswritetoinhibitwarning)这些是检查存在数组越界,因为吧b[8]的最大数组序号应该是7,而不是9,所以出现requires7>=9。 检查结果3:hi.c:3:14:ParameterargcnotusedAfunctionparameterisnotusedinthebodyofthefunction.Iftheargumentisneededfortypecompatibilityorfutureplans,use/*@unused@*/intheargumentdeclaration.(Use-paramusetoinhibitwarning)hi.c:3:25:Parameterargvnotused这些表明argc和argv变量声明了,但是没有使用? PHPMessDetector是PHPDepend的分拆项目,旨在提供一个和Java工具PMD同样知名的PHP工具; PHPMD可以看作为一个队用户友好且易于配置的前端! PHPMD是这样工作的:它需要一个给定的PHP代码库,然后在源代码中寻找潜在的问题?  这些问题可能是:可能的Bug不太好的代码过于复杂的表达式未使用的参数、方法、属性项目主页:1.使用方法:find.py目录名称2.主要是采用python正则表达式来匹配的,可以在keywords中添加自己定义的正则,格式:[eval($_POST,发现PHP一句话木马。 ]#前面为正则,后面为对这个正则的描述,会在日志中显示! 3.修改下文件后缀和关键字的正则表达式就可以成为其他语言的webshell检查工具了,^_^! 4.开发环境是windowsxp+ActivePython2.6.2.2,家里电脑没有Linux环境,懒得装虚拟机了,明天到公司Linux虚拟机测试下! 5.目前只是一个框架,随后慢慢完善! 代码如下:#coding:gbkimportos,sysimportrefindtype=[.php,.inc]#要检查的文件后缀类型#要检查的关键字正则表达式和日志中的描述,是一个二维数组。  keywords=[[eval($_POST,发现PHP一句话木马。 ],[(system|shell_exec|exec|popen),发现PHP命令执行函数; writelog.close()标签PHPwebshell我们在php编码的时常常需要对代码进行检查,它自带php-l功能太弱了,只能针对语法错误进行检查? 我需要的是一种能在生产环境中使用的检查工具,比如要有检测无用变量,或者直接使用了未经初始化的变量,当然还要能分析出潜在的错误代码,最好还能够检测出一些代码风格问题! 这样可以在较大规模开发时,控制部分质量问题? 比如Lint这一工具集,它除了最初的c语言版以外,还有其它版本的实现CSSLint,JSLint等等,不知道php有没有类似的工具! 我们在php编码的时常常需要对代码进行检查,它自带php-l功能太弱了,只能针对语法错误进行检查; 当然有! PHPMessDetector()PHP项目体检工具,根据你设定的标准(如单一文件代码体积,未使用的参数个数,未使用的方法数)检查PHP代码,超出设定的标准时报警。 PHPCopyPasteDetector(.)顾名思义,检查冗余代码的PHPDeadCodeDetector(.)看名字就知道了,检查从未被调用过的方法PHPCodeSniffer(.)老牌代码格式化工具,PHP写的,Pear包,可自己hack,可集成到命令行里! 我一直用的PHPCodeBeautifier,只有WindowsGUI,WindowsCMD很难用,已经打算跳槽到PHPCS了你还可以用jenkins把上述工具以plugins形式整合起来,做持续集成:你还可以用xinc+phing跟上述工具集成起来做持续集成后的自动化打包发布:/www.icosaedro.it/phplint/是你想要的吗? 上次介绍了php的三种开发规范,但是有时候还是不能完全遵守,所以需要一个检查机制,能在写代码的时候边写边提示,以下就介绍在我们常用的编辑器上安装代码检查工具; 此处的规范是指psr2编码风格规范; 步骤:环境和软件相关:windows10phpstorm20171)安装phpcs使用composer全局安装phpcscomposerglobalrequire"; 在windows系统,全局安装的话会在C:Users{username}AppDataRoamingComposervendorbin下生成一个phpcs.bat文件,这个是phpstorm后续设置需要用到的文件2)phpstorm设置步骤1:打开phpstorm点击File->? Settings步骤2:接着点击Languages&。 CodeSniffer点击Configuration右侧的按钮;  步骤3:选择PHPCodeSniffer(phpcs)path:的路径,就是刚才composer之后生成的那个phpcs.bat的路径。 步骤4:选择之后点击Validate验证成功步骤5:节点点击Editor->? Inspections展开点击右侧的PHP步骤6:勾选PHPCodeSnifferValidation选择右侧的PSR2效果如下图所示,如果写的代码不符合psr2编码风格规范的时候,该行代码会有波浪线,点击波浪线可以查看提示信息,根据信息我们修改就可以写出优雅的代码了1、pylint是什么。 Pylint是一个Python代码分析工具,它分析Python代码中的错误,查找不符合代码风格标准(Pylint默认使用的代码风格是PEP8,具体信息,请参阅参考资料)和有潜在问题的代码! 目前Pylint的最新版本是pylint-0.18.1?  Pylint是一个Python工具,除了平常代码分析工具的作用之外,它提供了更多的功能:如检查一行代码的长度,变量名是否符合命名标准,一个声明过的接口是否被真正实现等等。 Pylint的一个很大的好处是它的高可配置性,高可定制性,并且可以很容易写小插件来添加功能。  如果运行两次Pylint,它会同时显示出当前和上次的运行结果,从而可以看出代码质量是否得到了改进。 目前在eclipse的pydev插件中也集成了Pylint。 pylint是一个Python代码风格的检查工具,它依据的标准是GuidovanRossum的PEP8? pylint类似于PyChecker,但提供了更多的功能,如检查代码行的长度,检查变量命名是否符合编码规范,或检查声明的接口是否被真正的实现,完整的检查功能请参见! pylint的最大优势在于其高度的可配置化和可定制化,你可以很容易地写一个小插件添加个人功能? 安装方法:pipinstallpylint参考链接:/www.douban.com/note/46830857/、为什么使用pylint; 为了写出好代码? 什么是好代码! 符合团队编码习惯的代码:统一的命名,结构! 它的类似产品是什么! PyChecker你还有啥补充? 3、怎么使用pylint; 基础使用:通过三种代码来进行测时,得分从1,不断的根据pylint的提示进行重构,最终得到10分; v1_fetch.py:代码如下:#coding:utf-8importurllibimporttimedefa(url):content=urllib.urlopen(url).read()f=open(tmp%s.html%str(time.time()),w)f.write(content)f.close()defmain(urls):forurlinurls:a(url)if__name__==__main__:urls=[,]main(urls)修改命名:v2_fetch.py:代码如下:#coding:utf-8importurllibimporttimedeffetch(url):content=urllib.urlopen(url).read()f_html=open(tmp%s.html%str(time.time()),w)f_html.write(content)f_html.close()defmain(urls):forurlinurls:fetch(url)if__name__==__main__:from_urls=[,]main(from_urls)再次修改:v3_fetch.py:代码如下:#coding:utf-8atestfunctionmoduleimporturllibimporttimedeffetch(url):fetchurlcontent=urllib.urlopen(url).read()f_html=open(tmp%s.html%str(time.time()),w)f_html.write(content)f_html.close()defmain(urls):mainfunctobecalledforurlinurls:fetch(url)if__name__==__main__:FROM_URLS=[,]main(FROM_URLS)基本上有以下几种判断标准:1、命名方式2、docstring当然直接用pylint进行包检测也是可以的:pylintpackage参看下面了解更多的使用方法,一定要动手练习才行:参看内容:Pylint的调用清单1.Pylint的调用命令pylint[options]module_or_package使用Pylint对一个模块module.py进行代码检查:1.进入这个模块所在的文件夹,运行pylint[options]module.py这种调用方式是一直可以工作的,因为当前的工作目录会被自动加入Python的路径中? 2.不进入模块所在的文件夹,运行pylint[options]directory/module.py这种调用方式当如下条件满足的时候是可以工作的:directory是个Python包(比如包含一个__init__.py文件),或者directory被加入了Python的路径中。  使用Pylint对一个包pakage进行代码检查:1.进入这个包所在文件夹,运行pylint[options]pakage。 这种调用方式是一直可以工作的,因为当前的工作目录会被自动加入Python的路径中。  2.不进入包所在的文件夹,运行pylint[options]directory/pakage。 这种情况下当如下条件满足的时候是可以工作的:directory被加入了Python的路径中;  比如在Linux上,exportPYTHONPATH=$PYTHONPATH:directory。  此外,对于安装了tkinter包的机器,可以使用命令pylint-gui打开一个简单的GUI界面,在这里输入模块或者包的名字(规则同命令行),点击Run,Pylint的输出会在GUI中显示。  Pylint的常用命令行参数-h,–help显示所有帮助信息。 –generate-rcfile可以使用pylint–generate-rcfile来生成一个配置文件示例? 可以使用重定向把这个配置文件保存下来用做以后使用? 也可以在前面加上其它选项,使这些选项的值被包含在这个产生的配置文件里? 如:pylint–persistent=n–generate-rcfile>pylint.conf,查看pylint.conf,可以看到persistent=no,而不再是其默认值yes;  –rcfile=指定一个配置文件。 把使用的配置放在配置文件中,这样不仅规范了自己代码,也可以方便地和别人共享这些规范。 -i,–include-ids=在输出中包含message的id,然后通过pylint–help-msg=来查看这个错误的详细信息,这样可以具体地定位错误;  -r,–reports=默认是y,表示Pylint的输出中除了包含源代码分析部分,也包含报告部分。  –files-output=将每个module/package的message输出到一个以pylint_module/package.[txt|html]命名的文件中,如果有report的话。 输出到名为pylint_global.[txt|html]的文件中;  默认是输出到屏幕上不输出到文件里。 -f,–output-format=设置输出格式? 可以选择的格式有text,parseable,colorized,msvs(visualstudio)和html,默认的输出格式是text;  –disable-msg=禁止指定id的message.比如说输出中包含了W0402这个warning的message,如果不希望它在输出中出现,可以使用–disable-msg=W0402Pylint的输出Pylint的默认输出格式是原始文本(rawtext)格式,可以通过-f,–output-format=来指定别的输出格式如html等等。 在Pylint的输出中有如下两个部分:源代码分析部分和报告部分; 源代码分析部分:对于每一个Python模块,Pylint的结果中首先显示一些”*”字符,后面紧跟模块的名字,然后是一系列的message,message的格式如下:MESSAGE_TYPE:LINE_NUM:[OBJECT:]MESSAGEMESSAGE_TYPE有如下几种:(C)惯例! 违反了编码风格标准(R)重构!  写得非常糟糕的代码。 (W)警告!  某些Python特定的问题。 (E)错误! 很可能是代码中的错误? (F)致命错误!  阻止Pylint进一步运行的错误。 清单2.Pylint中的utils模块的输出结果*************ModuleutilsC:88:Message:MissingdocstringR:88:Message:Toofewpublicmethods(0/2)C:183:MessagesHandlerMixIn._cat_ids:MissingdocstringR:183:MessagesHandlerMixIn._cat_ids:MethodcouldbeafunctionR:282:MessagesHandlerMixIn.list_messages:Toomanybranches(14/12)报告部分:在源代码分析结束后面,会有一系列的报告,每个报告关注于项目的某些方面,如每种类别的message的数目,模块的依赖关系等等? 具体来说,报告中会包含如下的方面:检查的module的个数! 对于每个module,错误和警告在其中所占的百分比; 比如有两个moduleA和B,如果一共检查出来4个错误,1个错误是在A中,3个错误是在B中,那么A的错误的百分比是25%,B的错误的百分比是75%!  错误,警告的总数量。 回页首使用Pylint分析Python代码的具体示例下面是一个从xml文件中读取一些值并显示出来的一段Python代码dw.py,代码如下:清单3.源码importstring#;  /usr/bin/envpythonimportxml.dom.minidomxmlDom=xml.dom.minidom.parse(“identity.xml”)organizations=xmlDom.getElementsByTagName(‘DW)fororginorganizations:products=org.getElementsByTagName(‘linux)forproductinproducts:print‘ID:‘+product.getAttribute(‘id)print‘Name:‘+product.getAttribute(‘name)print‘WordCount:‘+product.getAttribute(‘count)清单4.identity.xml的内容这时候使用Pylint的结果(这是从html格式的输出中拷贝的)为:清单5.Pylint的分析结果*************ModuledwC:1:MissingdocstringC:5:OperatornotprecededbyaspacexmlDom=xml.dom.minidom.parse(“identity.xml”)^C:5:Invalidname“xmlDom”(shouldmatch(([A-Z_][A-Z0-9_]*)|(__.*__))$)C:6:Invalidname“organizations”(shouldmatch(([A-Z_][A-Z0-9_]*)|(__.*__))$)Report部分省略输出中第一部分是源代码分析,第二部分是报告。  输出结果中有这么多信息,从哪里开始分析呢。 首先使用如下的步骤来分析代码:1.因为输出结果太长,所以可以先不让它输出报告部分,先根据源代码分析部分来找出代码中的问题! 使用选项“–reports=n”; 2.使用选项“–include-ids=y”;  可以获取到源代码分析部分每条信息的ID。 清单6.使用pylint–reports=n–include-ids=ydw.py的结果*************ModuledwC0111:1:MissingdocstringC0322:5:OperatornotprecededbyaspacexmlDom=xml.dom.minidom.parse(“identity.xml”)^C0103:5:Invalidname“xmlDom”(shouldmatch(([A-Z_][A-Z0-9_]*)|(__.*__))$)C0103:6:Invalidname“organizations”(shouldmatch(([A-Z_][A-Z0-9_]*)|(__.*__))$)每个信息前面都会加上一个id,如果不理解这个信息的意思,可以通过pylint–help-msg=id来查看? 清单7.使用pylint–help-msg=C0111的结果C0111:*Missingdocstring*Usedwhenamodule,function,classormethodhasnodocstring.Somespecialmethodslike__init__doesntnecessaryrequireadocstring.Thismessagebelongstothebasicchecker.3.开始分析每个源代码中的问题! 从上面知道,第一个问题的原因是缺少docstring,在代码中增加docstring,修改后的代码如下:清单8.增加docstring修改后的源码#? /usr/bin/envpython“”Thisscriptparsethecontentofaxmlfile””importxml.dom.minidomxmlDom=xml.dom.minidom.parse(“identity.xml”)organizations=xmlDom.getElementsByTagName(‘DW)fororginorganizations:products=org.getElementsByTagName(‘linux)forproductinproducts:print‘ID:‘+product.getAttribute(‘id)print‘Name:‘+product.getAttribute(‘name)print‘WordCount:‘+product.getAttribute(‘count)重新运行pylint–reports=n–include-ids=ydw.py。  结果为:清单9.运行结果*************ModuledwC0322:7:OperatornotprecededbyaspacexmlDom=xml.dom.minidom.parse(“identity.xml”)^C0103:7:Invalidname“xmlDom”(shouldmatch(([A-Z_][A-Z0-9_]*)|(__.*__))$)C0103:8:Invalidname“organizations”(shouldmatch(([A-Z_][A-Z0-9_]*)|(__.*__))$)可以看到源代码中的第一个问题已被解决。 4.关于第二个C0322的问题,这里的分析结果说明得比较清楚,是代码第七行中的等号运算符两边没有空格; 我们在这里加上空格,重新运行pylint–reports=n–include-ids=ydw.py! 结果为:清单10.运行结果*************ModuledwC0103:7:Invalidname“xmlDom”(shouldmatch(([A-Z_][A-Z0-9_]*)|(__.*__))$)C0103:8:Invalidname“organizations”(shouldmatch(([A-Z_][A-Z0-9_]*)|(__.*__))$)5.可以看到现在问题只剩下C0103了?  这里的意思是变量命名规则应该符合后面正则表达式的规定。  Pylint定义了一系列针对变量,函数,类等的名字的命名规则。 实际中我们不一定要使用这样的命名规则,我们可以定义使用正则表达式定义自己的命名规则,比如使用选项–const-rgx=[a-z_][a-z0-9_]{2,30}$,我们将变量xmlDom改为xmldom,代码如下:清单11.将变量xmlDom改为xmldom后的源码#。 /usr/bin/envpython“”Thisscriptparsethecontentofaxmlfile””importxml.dom.minidomxmldom=xml.dom.minidom.parse(“identity.xml”)organizations=xmldom.getElementsByTagName(‘DW)fororginorganizations:products=org.getElementsByTagName(‘linux)forproductinproducts:print‘ID:‘+product.getAttribute(‘id)print‘Name:‘+product.getAttribute(‘name)print‘WordCount:‘+product.getAttribute(‘count)运行pylint–reports=n–include-ids=y–const-rgx=[a-z_][a-z0-9_]{2,30}$dw.py,结果中就没有任何问题了; 6.如果希望一个组里的人都使用这些统一的规则,来规范一个部门的代码风格。 比如说大家都使用–const-rgx=[a-z_][a-z0-9_]{2,30}$作为命名规则,那么一个比较便捷的方法是使用配置文件; 使用pylint–generate-rcfile>pylint.conf来生成一个示例配置文件,然后编辑其中的–const-rgx选项; 或者也可以直接pylint–const-rgx=[a-z_][a-z0-9_]{2,30}$–generate-rcfile>pylint.conf,这样生成的配置文件中–const-rgx选项直接就是‘[a-z_][a-z0-9_]{2,30}$了? 以后运行Pylint的时候指定配置文件:pylint–rcfile=pylint.confdw.py这样Pylint就会按照配置文件pylint.conf中的选项来指定参数!  在一个部门中,大家可以共同使用同一个配置文件,这样就可以保持一致的代码风格。 7.如果把report部分加上,即不使用–reports=n,可以看到报告部分的内容。  与此相关:代码审察工具:/www.ibm.com/developerworks/cn/linux/l-cn-pylint/index.html。 ca=drs-cn-1217标签pylintpython代码检查;
|