置顶随笔
#
摘要: 最近被老大拉去做服务器端自动化测试了,在这段期间,我一直找一些关于服务器端测试方案,自动化工具等等,无意间被我发现了Selenium这工具。在试用一段时间后,觉得Selenium确实是一个很不错的Web测试工具,同时也是开展自动化测试一个不错的切入点。在和强大的QTP比较后,我最后还是选择了使用Selenium,主要的原因是工具本身的灵活度很高,并且它也有利我日后对平台进行整合:>。
阅读全文
摘要: 2008年.Net编程人员工具参照......
原文:http://www.cnblogs.com/jaic-xiao/archive/2008/12/03/My2008UltimateDeveloperAndPowerUsersToolListForWindows.html
阅读全文
摘要: hyddd原创,转载请说明!
FindBugs是一个专门分析JAVA代码问题的静态代码扫描工具,它是由一位马里兰大学的博士写的,官方网站是:http://findbugs.sourceforge.net/index.html,里面有FindBugs工具的下载,并且也包含了那位博士写的关于静态代码分析引擎的一些论文,不过偶还没看。FindBugs可以发现的问题包括:多线程竞争问题,性能问题,安全问题,代码规范......这些下面我都会详细介绍:>,如果想了解更多关于其他语言的静态代码扫描工具信息,可以参考《[hyddd安全性测试笔记2]浅淡静态代码分析工具》。
阅读全文
2010年1月11日
#
摘要: Bug: Call to method of static java.text.DateFormatPattern id: STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE, type: STCAL, category: MT_CORRECTNESS As the JavaDoc states, DateFormats are inherently unsa...
阅读全文
2009年9月13日
#
dbunit是一个基于junit扩展的数据库测试框架。它提供了大量的类对与数据库相关的操作进行了抽象和封装。
一.官方网站:
二.中文资料
(1)DBUnit入门
(2)DBUnit实战
2009年6月10日
#
摘要: 原文:http://blog.sina.com.cn/s/blog_43aea3250100b9pu.html第一种方法: string AppPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; if (AppPath.EndsWith("\\") || AppPath.EndsWith("/")) AppPath= A...
阅读全文
摘要: 原文:http://blog.csdn.net/21aspnet/archive/2008/12/15/3522152.aspx一.获取当前函数名:[代码]结果:Test at offset 72 in file:line:column <filename unknown>:0:0,Test就是当前函数。二.获取源码文件名,当前函数,当前代码行,列:[代码]
阅读全文
2009年4月22日
#
[H B CN] Class defines clone() but doesn't implement Cloneable [CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE]
This class defines a clone() method but the class doesn't implement Cloneable. There are some situations in which this is OK (e.g., you want to control how subclasses can clone themselves), but just make sure that this is what you intended.
什么代码会引起这个问题呢?先看下面:
1: class MyTest {
2: public MyTest clone(){
3: MyTest test = new MyTest();
4: return test;
5: }
6: }
这段代码会引起FindBugs的这个警告,为什么?请看下面解释:
1.根据FindBugs的说明,如果一个类重写clone()函数,而不继承Cloneable接口,是一定有问题的,如果clone()方法只是简单进行克隆,如:new一个对象并初始化,然后返回这个新创建的对象的话,不继承Cloneable接口也是可以的。
2.如果是上面这样的话,为什么还要继承Cloneable接口呢?稍微说一下,Cloneable接口是不包含任何方法的!其实这个接口仅仅是一个标志,而且这个标志也仅仅是针对Object类中clone()方法的,如果clone类没有实现 Cloneable接口,并调用了Object的clone()方法(也就是调用了super.Clone()方法),那么Object的clone() 方法就会抛出CloneNotSupportedException异常。
3.所以这里建议是:规范写法,如果重写clone(),最好请继承Cloneable接口。
2009年4月1日
#
[M S XSS] Servlet reflected cross site scripting vulnerability
[XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER]
This code directly writes an HTTP parameter to Servlet output, which allows
for a reflected cross site scripting vulnerability. See http://en.wikipedia.org/wiki/Cross-site_scripting
for more information.
FindBugs looks only for the most blatant, obvious cases of cross site
scripting. If FindBugs found any, you almost certainly have
more cross site scripting vulnerabilities that FindBugs doesn't report. If you
are concerned about cross site scripting, you should seriously consider using a
commercial static analysis or pen-testing tool.
先看下面代码:
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
//
String v = request.getParameter("v");
//
PrintWriter out = response.getWriter();
out.print("协议版本号不对,v="+v);
out.close();
//
}
这里字符串v没有作过滤,直接返回给用户,有可能操作XSS攻击。具体关于XSS攻击的资料,可以参考上面Findbugs说明中的连接,这里就不多说了。
[M D ICAST] Result of integer multiplication cast to long
[ICAST_INTEGER_MULTIPLY_CAST_TO_LONG]
This code performs integer multiply and then converts the result to a long,
as in:
long convertDaysToMilliseconds(int days) { return 1000*3600*24*days; }
If the multiplication is done using long arithmetic, you can avoid
the possibility that the result will overflow. For example, you could fix the
above code to:
long convertDaysToMilliseconds(int days) { return 1000L*3600*24*days; }
or
static final long MILLISECONDS_PER_DAY = 24L*3600*1000;
long convertDaysToMilliseconds(int days) { return days * MILLISECONDS_PER_DAY; }
其实看上面的例子可以看到了
long convertDaysToMilliseconds(int days) { return 1000*3600*24*days; }
这段代码是有可能溢出的,建议把代码改为下面:
long convertDaysToMilliseconds(int days) { return 1000L*3600*24*days; }
用过VB6的人应该了解为什么会这样,因为在VB6里面一不小心就有可能出现这种溢出,在这里,JAVA认为:int * int * .....它的结果还是一个int!为什么编译器不能自动识别呢?答案是:很麻烦,并且这会使用编译器的效率非常低!对于有汇编经验的人来说,应该了解用汇编实现动态判断一个结果应该分配到一个long的空间还是int的空间有多复杂吧,而编译器有不能随便随便把int * int 的结果分配一个long空间,因为这会非常浪费内存,所以出于对效率和资源的考虑,最后的决定就是,凡是int * int * ....这样的计算结果一律都存放到int空间里,如果是long * int * .....则一律存放到long空间里,这就解释了为什么上面要在1000后面加个"L"了。:>
[M B DE] Method might ignore exception [DE_MIGHT_IGNORE]
This method might ignore an exception. In general, exceptions should be
handled or reported in some way, or they should be thrown out of the method.
try{
//
}
Catch(Execption ex){}
//
上面这段代码没有对ex进行任何处理。Findbugs在这里想说明的就是上面这个问题。
前面已经写了一篇文档说明Inconsistent synchronization,但最近做代码安全时候又发现了一些关于Inconsistent synchronization的新问题,所以追加说明一下。
我们先看一段较长的代码:
public class Test {
public static void main(String[] args) throws InterruptedException{
Test2 t2 = new Test2();
MyThread thread1 = new MyThread(t2,1);
t1.start();
for(int i=0;i!=1000;i++){
new MyThread(t2,2).start();
}
Thread.sleep(4000);
Integer a = t2.getA();
System.out.println("total:" + a);
}
}
class MyThread extends Thread {
public Test2 t2 = null;
public int num =0;
public MyThread(Test2 t2 , int num){
this.t2 = t2;
this.num =num;
}
public void run(){
if(num == 1){
try {
Integer a = t2.getA();
Thread.sleep(50);
t2.cleanA();
System.out.println("before clean:"+ a.toString());
} catch (InterruptedException e) {e.printStackTrace();}
}
else if(num == 2){
try{
t2.selfPlusPlus();
Thread.sleep(1);
}
catch (Exception e) { e.printStackTrace(); }
}
else
{
System.out.println("not run!");
}
}
}
class Test2 extends Thread {
private int a =100;
public synchronized void selfPlusPlus(){ a++; }
public synchronized void cleanA(){ a=0;}
public int getA() { return a; }
}
运行后我们得出一个结果:
before clean:100
total:835
Before clean =100,说明了我们的thread1是最先获得t2中的a的值!
我们的启了1000个线程去对t2做selfPlusPlus(a++)操作,正常是应该得到值是1000的,结果却是:835。
请看下面分析:
1.没有对变量 a做同步加锁,而是对操作的它的函数做同步加锁(如:public synchronized void selfPlusPlus(),public synchronized void cleanA()),这样做只能对同类操作加锁,不同类的操作,如:selfPlusPlus()和cleanA()互相之间同时对a的操作不会影响,看下面代码:
Public synchronized int test1(){
A = A+1;
//tag
A = A+1;
Return A
}
Public synchronized void test2(){
A=A-1;
}
cpu完全有可能在test1的"//tag"处进行线程切换,如果thread1和thread2都调用test1(),从thread1切换到thread2时,thread2发现资源被锁,则继续等待,cpu继续切换,然后thread1继续运行,但如果thread1调用test1(),而thread2调用teset2()呢,当在"//tag"处发生线程切换时,由于thread2资源没有被锁,故thread2可以正常执行,那么整个执行流程变为:A=A+1,A=A-1,A=A+1,结果是thread1的test1()返回了一个莫名其妙的数。
2.
进行原子操时没有加锁,第一个例子中,其实,getA()和cleanA()两者应该是一个原子操作,但没对操作的对象a加锁,导致出现问题。
我建议把上述代码修改为:
public void run(){
if(num == 1){
try {
Synchronized(t2.lock){
Integer a = t2.getA();
Thread.sleep(50);
t2.cleanA();
System.out.println("before clean:"+ a.toString());
}
//
else if(num == 2){
try{
t2.selfPlusPlus();
Thread.sleep(1);
}
//
class Test2 extends Thread {
//
Object lock = new Object();
//
public void selfPlusPlus(){
Synchronized(lock){
a++;
}
}
//
[M B Eq] Class defines compareTo(...) and uses Object.equals()
[EQ_COMPARETO_USE_OBJECT_EQUALS]
This class defines a compareTo(...) method but inherits its
equals() method from java.lang.Object. Generally, the
value of compareTo should return zero if and only if equals returns true. If
this is violated, weird and unpredictable failures will occur in classes such as
PriorityQueue. In Java 5 the PriorityQueue.remove method uses the compareTo
method, while in Java 6 it uses the equals method.
From the JavaDoc for the compareTo method in the Comparable interface:
It is strongly recommended, but not strictly required that
(x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class
that implements the Comparable interface and violates this condition should
clearly indicate this fact. The recommended language is "Note: this class has a
natural ordering that is inconsistent with equals."
重写compareTo有一定的风险,因为你不知道JDK内部做对象对比时,到底使用了compareTo还是equals。例如:在JAVA5 里,PriorityQueue.remove中使用了compareTo,但JAVA6中,PriorityQueue.remove使用了equals方法。
这里Findbugs强烈建议:(x.compareTo(y)==0) == (x.equals(y)),当你重写compareTo的时候,请记得这一点:>,当然这个只是建议,不是绝对的。
[H C EC] equals() used to compare array and nonarray [EC_ARRAY_AND_NONARRAY]
This method invokes the .equals(Object o) to compare an array and a reference that doesn't seem to be an array. If things being compared are of different types, they are guaranteed to be unequal and the comparison is almost certainly an error. Even if they are both arrays, the equals method on arrays only determines of the two arrays are the same object. To compare the contents of the arrays, use java.util.Arrays.equals(Object[], Object[]).
先看下面一段代码:
String[] strs = {"1"};
//
.
If("1".equals(strs)){
//todo
}
上面这段代码,if里面的代码是永远都不会被执行的,因为我们用了一个非数据(nonarray)和一个数组(array)做equals(),这里估计是写代码时的笔误。
2009年2月26日
#