代码审查技术-烽火PPT课件_第1页
代码审查技术-烽火PPT课件_第2页
代码审查技术-烽火PPT课件_第3页
代码审查技术-烽火PPT课件_第4页
代码审查技术-烽火PPT课件_第5页
已阅读5页,还剩145页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 代码审查技术 2 学习目标 掌握代码分析和评审技术掌握自动化代码分析工具的使用 3 建筑工程师的第一堂课 关注细节 关注并弄清楚桥梁修建细节 否则你建起来的桥就有可能坍塌 安全编程 代码静态分析 1940年TacomaNarrows大桥600英尺的一段坍塌落入普吉特湾 4 代码审查对成本的节省 5 黑盒测试的缺陷 黑盒测试既不充分 而且效率也低 在系统完成之前 测试就无法开始 测试人员只有软件版本发布时才能拿到版本进行测试 6 Staticwhite boxtesting FindbugsearlyFindbugsthatwouldbedifficulttouncoverorisolatewithdynamicblack boxtestingCosteffectiveSidebenefit giveblack boxtesterideasfortestcasestoapplywhentheyreceivethesoftwarefortesting 7 不懂开发怎么做代码审查 霍元甲因为他本人身体虚弱 所以父亲从小不让练武功 而生长在那样的环境中 他天天可以看到兄弟们在练功 招式已经记忆在心里 但是苦在没有练功的机会 他利用体力劳动的过程中 改变劳动方式 趁机练功 后来发展到独创 迷踪拳 8 代码静态分析 静态分析是指在不执行的情况下对代码进行评估的过程 包括 类型检查 风格检查 程序理解 BUG查找 安全审查 9 静态分析 类型检查 10 在Java中 下面的语句虽然符合类型检查规则 但是会在运行时失败 抛出一个ArrayStoreException异常 Object objs newString 1 objs 0 newObject 11 lint w2 lint e734 include stdafx h intmain charch 0 intn 0 ch n return0 VC6编译通过 但是PCLint可以通过静态代码检查找出类型转换造成的精度丢失问题 12 静态分析 风格检查 常见工具C C PC LintJAVA PMD NET StyleCop 风格检查更加挑剔 也更加注重空格 缩进 命名 注释 程序结构这些表面的东西 风格检查程序所展示的错误往往都是影响代码的可读性和可维护性的问题 13 typedefenum red green blue Color char getColorString Colorc char ret NULL switch c casered printf red returnret gcc的 Wall 选项将检查出其中的问题 14 15 typedefconstchar CSTRING CSTRINGrevere intlights CSTRINGmanner byland if lights 0 if lights 2 manner bysea elsemanner returnmanner intmain printf TheBritisharecoming s n revere 1 return0 16 静态分析 程序理解 程序理解工具能帮助我们搞懂代码库中的大量代码 洞察程序运转之道 集成开发环境 IDE 一般至少都包含某些程序理解功能 例如 查找本方法的所有应用 常用工具 代码流程图 CodeVisualtoFlowchart UML与源代码双向工程 例如Fujaba 17 18 Fujiaba能在UML视图和源代码之间来回转换 19 静态分析 Bug查找 BUG查找的目的不像风格检查那样抱怨格式方面的问题 而是根据 BUG惯用法 规则 来描述代码中潜在的缺陷 常用工具 PMD FindBugs Coverity Klocwork 20 EmptyCatchBlock EmptyCatchBlockfindsinstanceswhereanexceptioniscaught butnothingisdone Inmostcircumstances thisswallowsanexceptionwhichshouldeitherbeactedonorreported Example publicvoiddoSomething try FileInputStreamfis newFileInputStream tmp bugger catch IOExceptionioe 21 22 stringstr for inti 0 i 100 i str i ToString 23 静态分析 安全审查 最早的安全工具ITS4 RATS Flawfinder比素有美名的grep多不了多少东西 绝大多数情况下 它们将对代码进行扫描 寻找对strcpy 这样的函数所进行的调用 24 intmain intargc char argv charbuf1 1024 charbuf2 1024 char shortstring ashortstring strcpy buf1 shortstring safestrcpy buf2 argv 0 dangerous 好的安全分析工具将会区分出第一个strcpy调用是安全的 尽管可能不需要 而第2个调用则是危险的 25 静态安全分析工具测试基准 SecuriBench是一个基于Web的开源Java程序集合 包含一些已知的安全缺陷 http suif stanford edu livshits securibenchSecuriBenchMicro是SecuriBench的缩减版 http suif stanford edu livshits work securibench microABM AnalyzerBenchmark 测试基准由一些小程序和大型的真实程序构成 http samate nist gov比较静态安全分析工具的最佳方法是使用这些工具分析同一代码并比较其结果 26 把工具引入到代码审查流程中 27 28 练习 读代码 找错误 intmain intargc char argv charheightString 12 charweightString 12 intheight weight floatbmi printf Enteryourheightininches gets heightString printf Enteryourweightinpounds gets weightString height atoi heightString weight atoi weightString bmi float weight float height height 703 0 printf nBodymassindexis 2 2f n n bmi return0 29 通过代码审查找出常见安全问题 不恰当地处理输入缓冲区溢出错误和异常处理 30 审查输入处理错误 怀疑 审慎是安全之本 本杰明 富兰克林 绝对不要相信输入 程序员不得不接收用户输入 但是又不能够相信输入 那该怎么做呢 明智的方法是充分检查输入 并且验证输入的正确性 31 输入包括 命令行参数配置文件从数据库中检索出来的数据环境变量网络服务注册表值临时文件 32 不要盲目依赖数据库的数据来保证应用程序的正确运行 这段代码没有对查询所返回的记录行数进行检验 只是简单地调用返回的第一行记录 ResultSetrs stmt executeQuery rs next intbalance rs getInt 1 33 对来自数据库的数据加以验证 确保数据表中唯一值所对应的数据行的唯一性 如果存在2个数据行 则表明可能有攻击者试图插入伪造的数据行 修正后的代码检验了返回的数据行 以保证只返回一行数据 ResultSetrs stmt executeQuery if rs next thrownewLookupException 没有余额数据行 if rs isLast thrownewLookupException 余额数据行多余一行 intbalance rs getInt 1 34 千万不要依赖DNS域名或者IP地址来进行认证 因为如果攻击者获取了DNS更新权限 DNS缓存中毒 则可能将数据包路由到自己的机器上 或者伪装IP地址 使得系统误认为是同一个域中的机器 35 structhostent hp structin addrmyaddr char tHost myaddr s addr inet addr ip addr string hp gethostbyaddr char 36 黑名单vs 白名单 黑名单法 blacklisting 尝试枚举所有不能接受的输入值 白名单法 whitelisting 通过已知正确值清单来进行检查 37 下面是摘自Tomcat5 1 31版本中的一段程序 采用了一个黑名单 假定在Web页面中只有4个特殊的字符输入才会导致程序的安全问题 for inti 0 i resule append 38 黑名单法只拒绝已知恶意的数据 而在给定环境中 恶意值的集合通常是难于枚举的 或者可能是无限的 所以黑名单法一般是不完善的 即使可能列出一个危险输入值的完整清单 也很可能随着时间的变迁而过时 黑名单法是不利于应用程序安全的 39 40 审查缓冲区溢出错误 缓冲区溢出 bufferoverflow 将大量数据塞入一个较小的缓冲区中所导致的程序漏洞缓冲区溢出通常被攻击者用于重写内存中的数据 近10年来 缓冲区溢出漏洞的数量没有明显下降的趋势 41 42 voidtrouble inta 32 charline 128 gets line 缓冲区溢出就是将长度超过缓冲区大小的数据写入程序的缓冲区 造成缓冲区的溢出 从而破坏程序的堆栈 使程序转而执行其他指令 当一个超长的数据进入到缓冲区时 超出部分就会被写入其他缓冲区 其他缓冲区存放的可能是数据 下一条指令的指针 或者是其他程序的输出内容 这些内容都被覆盖或者破坏掉 可见一小部分数据或者一套指令的溢出就可能导致一个程序或者操作系统崩溃 43 天生危险的函数 gets cin scanf strcpy wcscpy lstrcpysprintf fprintf swprintf 44 禁用函数列表 45 Linux和Windows平台上替换C类库的字符串解决方案 GNU LinuxBstrlib FireString http firestuff org wordpress projects firestringGLib http developer gnome org doc API 2 0 glib index htmlLibmib 46 审查整数溢出错误 当一个整数值大于或者小于其范围时 就会产生整数溢出错误 integeroverflow 回绕 47 unsignedlongreadamt readamt getstringsize if readamt 1024 return 1 readamt buf malloc readamt 如果getstringsize返回0 则readamt 1将等于4294967295 无符号32位整数的最大值 这个操作可能会因为内存不足而失败 48 检测整数溢出 49 IntSafe数学函数 对于C语言 微软开发了IntSafe类库 它可以帮助检测和防止整数操作中的漏洞IntSafe函数库包含200多个转换函数 50 审查异常处理错误 charbuf 10 cp buf 10 fgets buf 10 stdin strcpy cp buf buf 如果发生I O错误 fgets将不给buf添加NULL终止符 在buf中缺少NULL终止符将可能会导致在后续的strcpy调用时发生缓冲区溢出 51 Trycatchfinally C 和Java都支持try finally的语法 不论异常是否抛出 finally模块总是在try模块后执行 但是 如果finally模块包含一个return语句 将抑制异常抛出 52 审查资源泄漏问题 未能及时释放资源 包括数据库对象 文件句柄和套接字 可能会导致严重的性能问题 在C程序中 在单个函数体中查找多个return语句 通常是分布式错误处理代码的标志 也是资源泄漏的滋生地 53 函数有多个出口时 没有在每个出口处对动态申请的内存进行释放 一般在异常处理时容易出现这种错误 下面的代码段就是这样的例子 pRecord newchar pTable GetRecordLength assert pRecord NULL if pTable GoTop FALSE DBIERR NONE return 如果从这里返回 pRecord将得不到释放 pTable Close delete pRecord 54 char getBlock intfd char buf char malloc BLOCK SIZE if buf returnNULL if read fd buf BLOCK SIZE BLOCK SIZE returnNULL returnbuf 如果read调用失败 将导致已经分配的buf内存泄漏 55 try Statementstmt conn createStatement ResultSetrs stmt executeQuery CXN SQL harvestResult rs stmt close catch SQLExceptione logger log Level ERROR errorexecutingsqlquery e 如果在执行SQL或处理结果时出现了异常 那么stmt对象将不能被关闭 假如这种情况经常发生 数据库将耗尽可用的指针 不能执行任何其他的查询 56 C C 代码审查 C C 语言编码规范C C 常见代码问题检测 57 循环语句的效率 for row 0 row 100 row for col 0 col 5 col sum sum a row col 58 在多重循环中 如果有可能 应当将最长的循环放在最内层 最短的循环放在最外层 以减少CPU跨切循环层的次数 for col 0 col 5 col for row 0 row 100 row sum sum a row col 59 指针的使用 UC puc card config tab Get Config Table AMP CPM CARD CONFIG TABLE b middle data ok generate trans middle data from original data puc card config tab Ul card config num 60 分配资源是否正确释放 voidWarnSvr SaveWarnData for intm 0 mCsn Buffer EVENT ALARM m Csn item Position m RecordsInHistoryFile RecordsInBuffer EVENT ALARM IfawarnwithacertainCsnisnotinEventFilterIndex itisnotnecessarytobeaddedtoHistoryFilterIndexintitem total EventFilterIndex GetItemsInContainer BOOLfind flag false for intk 0 kCsn item Csn find flag true break if find flag HistoryFilterIndex Add item if HistoryFilterIndex IsFull ClearIndexEntry 61 PC Lint LINT工具是一种软件质量保证工具 许多国外的大型专业软件公司 如微软公司 都把它作为程序检查工具 在程序合入正试版本或交付测试之前一定要保证通过了LINT检查 他们要求软件工程师在使用LINT时要打开所有的编译开关 如果一定要关闭某些开关 那么要给出关闭这些开关的正当理由 PC LINT是GIMPELSOFTWARE公司的产品 其中的内容是非常广泛的 光是选项就有300多个 涉及到程序编译及语法使用中的方方面面 62 练习 PC Lint的安装和使用 1 2 char report shortm shortn char p 3 4 intresult 5 char temp 6 longnm 7 inti k kk 8 charname 11 JoeJakeson 9 10 nm n m 11 temp p null p 12 for i 0 i0 result 1 16 elseif kk 0 result 1 17 if m result returntemp 18 elsereturnname 19 63 Off By OneExample includeintmain inti inta 1 2 3 intn sizeof a sizeof int for i 0 i n i printf a d d n i a i return0 64 defineNStu3000 defineNCrs400externintconstStuCourse NStu NCrs externdoubleconstCostBook NCrs doubletotal cost inti j doublecost 0 for i 0 i NStu i for j 0 j NCrs i cost StuCourse i j CostBook j returncost 65 JAVA代码审查 代码审查和语法错误检查是两个不同层次的概念 语法错误是低层次 强制性的检查 任何违反语法的程序都是无法通过编译的 也就是说可运行的程序必须是语法正确的 而代码审查是高级别 非强制性的检查 它对语法正确的程序施加了更高更严格的要求 从而提升程序的可读性 降低因变量命名 方法定义 程序逻辑的不完整性等问题而导致程序的潜在出错机率 增加程序的可维护性和健壮性 66 switch StatementShouldIncludeaDefaultCase 1 switch formatType 2 3 case1 4 formatStr yyyyMMddHHmmss 5 break 6 case2 7 formatStr yyyy MM ddHH mm ss 8 break 9 case3 10 formatStr yyyy MM ddHH mm ss 11 break 12 case4 13 formatStr yyyy 年 MM 月 ddHH mm ss 14 break 15 67 根据Sun的编码规范 每个switch流程控制语句都必须带一个default分支 以保证逻辑分支的完整性 如果没有第15 16行的default代码 代码审查将给出警告 1 switch formatType 2 3 case1 4 formatStr yyyyMMddHHmmss 5 break 6 case2 7 formatStr yyyy MM ddHH mm ss 8 break 9 case3 10 formatStr yyyy MM ddHH mm ss 11 break 12 case4 13 formatStr yyyy 年 MM 月 ddHH mm ss 14 break 15 default 16 formatStr yyyy MM ddHH mm ss 17 68 AccessingStaticMembersbytheDescendantClassName 1 publicclassASMO12 3 voidfunc 4 5 ASMO1obj1 newASMO1 6 ASMO2obj2 newASMO2 7 obj1 attr 10 8 obj2 attr 20 9 obj1 oper 10 obj2 oper 11 this attr 12 this oper 13 14 15 staticintattr 16 staticvoidoper 17 18 19 20 classASMO221 22 staticintattr 23 staticvoidoper 24 25 69 类中所有的静态方法或变量都应该通过类名来引用 如果通过类的实例来引用这些静态的成员将影响到程序的可读性 如果通过类名来引用静态变量 将容易分辨出这些成员的静态属性 因为类静态成员变量在JVM中仅存在一份 而非每个对象实例各自一份 因此静态成员变量可以看成类的成员 70 ComplexAssignment 1 inti 0 2 intj 0 3 intk 0 4 intl 0 5 i j 6 7 k j 10 8 9 l j 15 10 11 i j 20 12 13 i j 25 30 14 15 i j 20 16 17 i j 25 30 71 往往有些程序员热衷于将Java的语法发挥到极致 以资其对Java语法精通的凭据 如果是为了练习语法 理解语法 无可厚非 但如果在需要充分协作沟通的软件项目中 简洁明了 清晰易懂将会受到推崇 晦涩难懂的语句将会受到奚落 故此 大部分的软件公司的规范都对语句的精简明了提出了要求 72 ComplexInitializationorUpdateClausesin for Loops 1 for i 0 j 0 k 10 l 1 i 10 i j k l 2 2 3 dosomething4 73 由于for循环控制语句的高度灵活性 所以for 中的代码往往是复杂晦涩代码的乐园 在for语句中以逗号分隔的赋值语句最多不应超过3个 1 for i 0 j 0 k 10 l 1 i 10 i j k l 2 2 3 dosomething4 5 应改写成下面的样式6 l 1 7 for i 0 j 0 k 10 i cnt i j k 8 9 dosomething10 l 2 11 74 UseAbbreviatedAssignmentOperator 1 voidoper 2 inti 0 3 i i 20 4 i 30 i 5 75 在可能的情况下使用缩减赋值运行符 12 76 CodingStyle MultipleStatementsonOneLine PlaceStatementinBlock Use L insteadof l attheEndofIntegerConstants 1 i j 23 if val 10 6 val 10 7 8 voidfunc 9 longvar 0 x0001111l 10 77 不应将多行语句写在同一行代码中 代码块应以 框起来 虽然增长了代码 但代码结构性更强 声明长整型使用大写的 L 类型指定符 而非小写的 l 因为后者和数字1相似 78 HidingNames 1 publicclassHideName2 3 intindex 4 voidfunc 5 6 intindex 7 dosomething8 9 voidsetIndex intindex 10 11 this index index 12 index 13 14 79 类成员变量被局部变量隐藏 因类方法体中的局部变量和类成员变量具有相同的名字 而使成员变量被屏蔽1 publicclassHideName2 3 intindex 4 voidfunc 5 6 intindex 隐藏了成员变量index 应改成另一个名字 如intnewIndex 7 dosomething8 9 voidsetIndex intindex 10 11 this index index 该语句行中带this显式引用成员变量进行赋值 审查规则将不报警12 index 该语句行没有this显式引用 审查规则将报警13 14 80 HidingInheritedField 1 classWindow2 3 protectedintstyle 4 5 6 classButtonextendsWindow7 8 protectedintstyle 9 81 子类成员变量隐藏父类成员变量 子类成员变量和可继承的父类成员变量名字相同 1 classWindow2 3 protectedintstyle 4 5 6 classButtonextendsWindow7 8 protectedintstyle 具有和父类相同的成员变量 应改为另一个名字 如anStyle9 82 HidingInheritedStaticMethods 1 classAnimal2 3 staticvoidoper1 4 staticvoidoper2 5 6 7 classElephantextendsAnimal8 9 staticvoidoper1 10 staticvoidoper2 11 83 子类覆盖父类静态方法 和非静态的方法覆盖不一样 静态的父类方法不应被子类覆盖 成员变量和局部变量的隐藏 常常会使开发人员张冠李戴 犯一些不经意的错误 而子类隐藏父类的成员和静态变量常常是由于没有注意到父类中已经具有相同的名字而引起的 由此而生产的程序Bug由于其隐身性强 是很难被发现 1 classAnimal2 3 staticvoidoper1 4 staticvoidoper2 5 6 7 classElephantextendsAnimal8 9 staticvoidoper1 隐藏了父类中的静态方法 应取另一个名字 如anOper1 10 staticvoidoper2 隐藏了父类中的静态方法 应取另一个名字 如anOper2 11 84 UseConventionalVariableNames 1 voidmethod doubled 2 3 inti 4 Exceptione 5 chars 6 Objectf 7 Stringk 8 ObjectUK 9 ObjectCOM 10 85 避免用过于简单的变量名除了循环体中的临时变量 及一些没有特殊意义的常见数据类型 应该尽量避免使用一个字符作为变量 那些无特殊意义且常见的数据类型 所选取的单字符变量名必须按表1进行命名 为了减少潜在的冲突 避免不必要的混淆 不允许以大写域名或国家代码作变量名 1 voidmethod doubled 2 3 inti 4 Exceptione 5 chars 应该改为c6 Objectf 应该改为o7 Stringk 应该改为s8 ObjectUK 和英国国家代码相同 应改为其他的名字 如ukObj9 ObjectCOM 和域名相同 应改为其他的名字 如obj 110 86 BreakStatementisMissingbeforeCaseclause 1 switch c 2 case 3 4 break 5 case 6 7 case n 8 9 case case t 10 11 break 12 87 根据Sun编码惯例 程序入口点从一个case进入 直接到达下一个case代码段 前一个case没有对应的break语句时 在跨过的地方必须给出一个显示的注释 表示是特定流程控制的要求 而非无意遗漏 88 Non CaseLabelinSwitchstatement 1 publicclassCaseLabel2 3 点 4 publicstaticfinalintPOINT 1 5 线 6 publicstaticfinalintLINE 2 7 多边形 8 publicstaticfinalintPOLYGON 3 9 10 publicStringgetFigureType intkind 11 12 StringtempName null 13 switch kind 14 15 casePOINT 16 LINE 17 tempName POINTandLINE 18 break 19 casePOLYGON 20 tempName POLYGON 21 break 22 default 23 tempName UNDEFINE 24 25 returntempName 26 27 89 在switch中出现非case的标签 在Java语句中有两个标签 即case分支标签 另一个则是语句标签 如果case分支标签语句误删或遗漏了case关键字 则case分支标签将变成语句标签 而编译器无法识别这个错误 90 SuspiciousBreak Continue 1 voidscan char arr 2 3 loop 4 for inti 0 i arr length i 5 6 switch arr i 7 8 case 0 case 1 case 2 case 3 case 4 9 5 6的数字10 case 5 case 6 case 7 case 8 case 9 11 12 if processDigit arr i 13 14 continueloop 15 16 else17 18 break 19 20 21 case case t 22 23 processWhitespace arr i 24 continue 25 26 default 27 processLetter arr i 28 break 29 30 91 有错误嫌疑的break和continue break和continue用于switch和循环中的跳转控制 break用于提前结束循环以及从switch中退出 break的这种 多态性 使得在循环体中内嵌switch语句时 常会带来一些隐患 即开发者本希望退出外层循环 结果却只退出内层的switch语句而已 92 ComparingFloating PointValues 1 voidcalc doublelimit 2 3 if limit 0 0 4 5 System out println thefloat pointnumberisexactly0 6 7 93 避免对浮点值进行等值逻辑判断浮点数都是一定精度的数据 由于内部表示的误差 往往字面上相同的两个浮点数 其内部表示也不完全相同 故此应避免对浮点值数进行等值逻辑判断 而应采用逻辑比较判断 1 voidcalc doublelimit 2 3 if limit 0 0 应改为通过和较小值比较来判断 如if Math abs limit 0 0000001 4 5 System out println thefloat pointnumberisexactly0 6 7 94 MixingLogicalOperatorsWithoutParentheses 1 booleana b c 2 3 if a b c 4 5 6 95 添加 清晰化复杂的表达式写复杂的表达式时不应过度依赖运算操作符的计算优先顺序 而应养成使用 的好习惯 当一个逻辑表达式由多个逻辑运算组成时 应该用 划分不同的部分 1 booleana b c 2 3 if a b c 应该替换成if a b c 4 5 6 96 MemberisNotUsed 1 publicclassUnuse2 3 privateStringname 4 publicObjectvalue 5 6 privateObjectgetValue 7 8 returnvalue 9 10 11 privatevoidprint 12 13 System out println getValue value 14 15 97 类中private的成员方法和成员变量不可能在外部类中调用 如果发现private的成员变量或方法并没有在内部的protect或public方法中使用 即这个成员永远不会在运行期得到引用 而成为一个无用的成员变量和方法 代码清单中name变量 getValue 及print 方法都是无用的方法 因为不可能通过外面的类访问到这些成员 Unuse也没有提供调用这些成员的接口 所以这些成员都可以从类中清除 98 ComparisonalwaysproducestheSameResult 1 voidhandleEvent Evente 2 if e null 3 4 if e null 5 6 7 8 9 10 voidputChar charc booleanisLetter booleanisDigit 11 if isDigit 12 booleanisLetterOrDigit isLetter isDigit 13 14 15 99 无作为的表达式比较表达式总是返回相同的值 1 voidhandleEvent Evente 2 if e null 3 4 if e null 该表达式的值永远都是false 因为进入这个代码段的e恒为非空5 6 7 8 9 10 voidputChar charc booleanisLetter booleanisDigit 11 if isDigit 12 booleanisLetterOrDigit isLetter isDigit 该表达式的值永远都是true13 14 15 100 OperationhasNoEffect 1 publicclassNoEffect2 3 privateStringname 4 privateintindex 5 6 NoEffect Stringn intindex 7 8 this name name 9 this index index 10 11 12 intgetPosition 13 14 intbase 0 15 returnindex base 16 17 18 intgetModule 19 20 intx 1 y 2 21 returnx y 22 23 101 无效的算术运算 例如 当进行加法和减法运算时 有一个操作数是0 当进行乘法运算时 乘法或被被乘数为1 当进行除法运算时 除数为1 当进行取模运算时 左边的操作数的绝对值比右边操作数的绝对值小 此时x y x 属性赋值时 将本身的值赋给自己 102 StatementisUnreachable 1 int arr newint size 2 if arr null 3 4 returnnull 5 103 流程控制中存在不可到达的语句有些流程控制由于测试条件恒为false 则流程中的程序无法到达 1 int arr newint size 2 if arr null 由于arr不为空 则该测试逻辑不可能通过 程序无法进入该程序块中3 4 returnnull 5 104 JBuilder的CodeAudits功能的使用 JBuilder根据Sun的编码规范及软件开发界总结出的一套行之有效的编码习惯 对Java开发中的编码风格 声明风格 Javadoc文档注释 EJB规范 命名风格 潜在错误 编码中的画蛇添足等诸多方面进行代码审查并给出警示 以便开发人员发现这些不足和隐患予以及时更正 105 C 代码审查 C 编码规范C 常见代码问题检测 106 避免不必要的强制转换 publicstaticvoidUnderPerforming ArrayListlist foreach objectobjinlist if objisControl ControlaControl objasControl UseaControl 107 使用字符串长度属性测试是否为空字符串 strings1 test publicvoidEqualsTest if s1 Console WriteLine s1equalsemptystring 108 优先使用交错数组而非多维数组 int multiDimArray 1 2 3 4 5 6 7 0 8 0 0 0 9 0 0 0 109 属性不应返回数组 publicclassTest string nameValues publicTest nameValues newstring 100 for inti 0 i 100 i nameValues i Sample publicstring Names get return string nameValues Clone publicstaticvoidMain Testt newTest for inti 0 i t Names Length i if t Names i SomeName Performsomeoperation 110 publicclassPhotoLibrary privatePhoto photos null publicPhoto Photos get Photo copyOfPhotos newPhoto photos Length for inti 0 ilibrary Photos i Height Console WriteLine Landscape elseif library Photos i Width library Photos i Height Console WriteLine Portrait else Console WriteLine Square 111 避免过多的继承 classBaseClass classFirstDerivedClass BaseClass classSecondDerivedClass FirstDerivedClass classThirdDerivedClass SecondDerivedClass classFourthDerivedClass ThirdDerivedClass classFifthDerivedClass FourthDerivedClass 112 避免异常的发生 privatevoidDrawBox Rectanglerect Brushbrush Graphicsg this CreateGraphics try g FillRectangle brush rect catch ArgumentNullException g FillRectangle SystemBrushes Desktop rect finally g Dispose 113 控制异常 foreach stringexpinexpressions try intnum int Parse exp s num catch FormatException Console WriteLine exp 包含无效的Int32数值 catch OverflowException Console WriteLine exp 溢出 114 注意多个catch子句的排列顺序 try if path null FileStreamfstream File Open path FileMode Open catch ArgumentException MessageBox Show 文件名格式不正确或包含非法字符 catch ArgumentOutOfRangeException MessageBox Show 无效的打开文件模式 115 异常信息的隐藏 publicAccountInfoSignIn stringuserName byte key byte savedKey GetSavedKeyByUserName userName try for inti 0 i savedKey Length i if savedKey i key i thrownewInvalidPasswordException 密码无效 returnGetAccountInfo userName catch IndexOutOfRangeExceptionex thrownewInvalidPasswordException 密码无效 ex 116 异常提示信息 thrownewArgumentOutOfRangeException age 年龄不能为负数 117 访问控制 publicstructPerson publicintAge publicclassProgram publicstaticvoidmain Personperson person Age 3 字段其实就是结构或类中的普通变量成员 这将意味着 一旦字段被公开 对其的访问便处于完全失控的状态 118 FxCop FxCop是一款专门用于分析 NET托管代码程序集的工具 它能检查 NET代码是否满足Microsoft NETFramework设计规范 它使用反射 MSIL解析等技术来分析程序集 可以检查超过200个缺陷 包括库设计 本地化 命名规范 性能 安全等方面的内容 119 FxCop的使用 120 FxCop命令行运行方式 FxCopCmd f F CNJ C6 CodeAnalysisTest1 CodeAnalysisTest1 bin Debug CodeAnalysisTest1 exe out C 1 txt s rule E ProgramFiles MicrosoftVisualStudio8 TeamTools StaticAnalysisTools FxCop Rules DesignRules dll ruleid Microsoft Design CA2210 121 练习 利用FxCop检查C 代码问题 privatevoidbutton1 Click objectsender EventArgse stringstr for inti 0 i 100 i str i ToString 122 FxCop的规则定义方法 FxCop支持用户自定义检查规则 通过使用FxCop的SDK 继承基类BaseIntrospectionRule 并编写自定义的检查方法 可针对项目的代码添加更多的检查规则 123 FxCop的代码分析原理 大多数代码分析工具扫描的是源代码 但是FxCop则直接对编译好的代码进行扫描 NET的每个程序集都有metadata 可称为元数据 metadata是关于一个程序集中各元素的类型信息库 它本身也存放在这个程序集中 metadata对程序集以及程序集内用到的所有类型进行描述 FxCop会利用metadata的信息来获得代码内部的运行情况 另外 FxCop也对代码编译时生成的中间语言 MSIL 进行检查 通过对metadata和MSIL检查的结合 FxCop可以得出大量信息 以此获得对代码执行时的行为的相关信息 它把代码和各条规则逐一比较检查 当找到不符合规则的代码时就会生成一条消息 124 练习 定义FxCop代码检查规则 125 DevPartner DevPartnerStudio8 0ProfessionalEdition是一款与VisualStudio紧密结合的测试工具 它能帮助检测和诊断各种 NET代码问题 包括代码评审 CodeRev

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论