コードの質が低いと、予測できない動作につながります。ユーザーの視点には、それがしばしば使い勝手の悪さとなって現れます。攻撃者にとっては、予期せぬ方法でシステムにストレスを与える機会となります。
assert
Solidity 関数を使用して、false ステートメントをチェックしています。assert
Solidity 関数は、true
に評価するステートメントをチェックすることのみを目的としています。false
ステートメントがこの関数に渡されると、正しく機能していないコードや、入力の検証などのために誤用されている関数が示されます。assert
関数を使用して、false ステートメントをチェックします。
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
であるため、述部 getChunk == NULL
は常に false になります。
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();
}
}
}
}
getAccessLevel()
をインスタンス user
にコールしているのであって、クラス User
や RegularUser
にコールしているのではないため、この場合は常に true
が返され、instanceof
が使用される場合でも、if/else
ブロックのこの部分に到達するために操作が制限されます。serialPersistentFields
を正しく使用するには、private
、static
、および final
として宣言する必要があります。serialPersistentFields
配列内で指定して、クラスの Serializable フィールドを手動で定義できるようになります。この機能は、serialPersistentFields
が private
、static
、および final
として宣言されている場合にのみ奏功します。serialPersistentFields
が、private
、static
、および final
ではないため、Serializable
フィールドの定義には使用されません。
class List implements Serializable {
public ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("myField", List.class) };
...
}
java.util.Arrays.equals().
ではなく Object.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_push()
で作成されるデータ構造は、pthread_cleanup_pop()
への後続のコールで利用できなくなります。このコードは、これらの関数がマクロとして実装されているすべてのプラットフォームでコンパイルに失敗するか、あるいは、ランタイム時の動作が不正となります。
void helper() {
...
pthread_cleanup_push (routine, arg);
}