Códigos de baixa qualidade levam a comportamentos imprevisíveis. Da perspectiva do usuário, isso normalmente se manifesta como usabilidade ruim. Para um invasor, trata-se de uma oportunidade para atacar o sistema de formas imprevistas.
assert
do Solidity para verificar uma declaração falsa.assert
do Solidity destina-se a verificar apenas instruções avaliadas como true
. Ter uma instrução false
passada para essa função indica que o código não está funcionando corretamente ou que a função está sendo mal utilizada, por exemplo, para validar a entrada.assert
para verificar uma instrução falsa.
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
sempre será "false", pois getChunk
é o nome de uma função definida no programa.
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()
em relação à instância user
, e não contra as classes User
ou RegularUser
, isso significa que essa condição sempre retornará true
e a operação restrita será realizada mesmo que instanceof
tenha sido usado para entrar nessa parte do bloco if/else
.serialPersistentFields
corretamente, ele deve ser declarado como private
, static
e final
.serialPersistentFields
. Esse recurso somente funcionará se serialPersistentFields
for declarado como private
, static
e final
.serialPersistentFields
não será usado para definir campos Serializable
, pois não é private
, static
e final
.
class List implements Serializable {
public ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("myField", List.class) };
...
}
Object.equals()
em um array no lugar de java.util.Arrays.equals().
Object.equals()
contra um array é um erro na maioria dos casos, pois isso verificará a igualdade dos endereços dos arrays, em vez da igualdade dos elementos dos arrays, e, em geral, deve ser substituído por 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()
a fim de enviar a função routine
para a pilha de limpeza do thread de chamada e, em seguida, é retornado. Como pthread_cleanup_push()
e sua função parceira pthread_cleanup_pop()
são implementadas como macros em plataformas diferentes do IBM AIX, a estrutura de dados criada por pthread_cleanup_push()
não será acessível a chamadas subsequentes para pthread_cleanup_pop()
. O código não conseguirá compilar ou apresentará um comportamento incorreto em tempo de execução em todas as plataformas nas quais essas funções são implementadas como macros.
void helper() {
...
pthread_cleanup_push (routine, arg);
}