程式碼品質不佳,會導致無法預料的行為。從使用者的角度來看,這通常表現為可用性不佳。對於攻擊者而言,這提供了以意想不到的方式向系統施加壓力的機會。
assert
Solidity 函數來檢查 false 陳述式。assert
Solidity 函數主要用於僅檢查解算為 true
的陳述式。若將 false
陳述式傳遞至此函數,則會指出程式碼無法正常運作或函數被誤用,例如驗證輸入。assert
函數來檢查錯誤的陳述式。
contract A {
B b = new B(7);
function checkWithAssert(){
assert(b.retValue() == 21);
...
}
}
contract B {
uint _par;
constructor(uint par){
_par = par;
}
function retValue() returns(uint){
return _par;
}
}
getChunk == NULL
述詞會一直為 false,因為 getChunk
是定義於程式中的函數名稱。
if (getChunk == NULL)
return ERR;
char* getName() {
char name[STR_MAX];
fillInName(name);
return name;
}
class AccessLevel{
public static final int ROOT = 0;
//...
public static final int NONE = 9;
}
//...
class User {
private static int access;
public User(){
access = AccessLevel.ROOT;
}
public static int getAccessLevel(){
return access;
}
//...
}
class RegularUser extends User {
private static int access;
public RegularUser(){
access = AccessLevel.NONE;
}
public static int getAccessLevel(){
return access;
}
public static void escalatePrivilege(){
access = AccessLevel.ROOT;
}
//...
}
//...
class SecureArea {
//...
public static void doRestrictedOperation(User user){
if (user instanceof RegularUser){
if (user.getAccessLevel() == AccessLevel.ROOT){
System.out.println("doing a privileged operation");
}else{
throw new RuntimeException();
}
}
}
}
user
實例 (而不是針對 User
或 RegularUser
類別) 呼叫 getAccessLevel()
方法,因此這將意味著,此狀況一律會傳回 true
,並且會執行限制的操作,即使使用 instanceof
以進入 if/else
區塊的此部分也是如此。serialPersistentFields
,就必須將其宣告為private
、static
及 final
。serialPersistentFields
陣列中指定類別的可序列化欄位來手動定義這些欄位。這項功能只有在宣告 serialPersistentFields
為 private
、static
以及 final
時才有效。serialPersistentFields
的宣告,來定義 Serializable
欄位,因為欄位不是 private
、static
以及 final
。
class List implements Serializable {
public ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("myField", List.class) };
...
}
Object.equals()
,而不是呼叫 java.util.Arrays.equals().
Object.equals()
是錯誤的,因為這將會檢查陣列的位址是否相等,而不是陣列的元素是否相等,所以通常應該由 java.util.Arrays.equals()
取而代之。 Object.equals()
函數嘗試檢查兩個陣列。
...
int[] arr1 = new int[10];
int[] arr2 = new int[10];
...
if (arr1.equals(arr2)){
//treat arrays as if identical elements
}
...
pthread_cleanup_push()
使 routine
函數呼叫執行緒清除堆疊並回傳結果。因為 pthread_cleanup_push()
和它的相鄰函數 pthread_cleanup_pop()
被視為巨集而在除了 IBM AIX 以外的平台上實作,所以之後呼叫 pthread_cleanup_pop()
時,不會存取由 pthread_cleanup_push()
建立的資料結構。在這些函數被視為巨集而實作的所有平台上執行此程式碼,將會無法進行編譯或無法正常操作。
void helper() {
...
pthread_cleanup_push (routine, arg);
}