Uma API é um contrato entre quem chama e o que se chama. As formas mais comuns de abuso de API ocorrem quando o responsável pela chamada não respeita sua parte do contrato. Por exemplo, se um programa não chama chdir() após chamar chroot(), ele viola o contrato que especifica como alterar o diretório raiz ativo de forma segura. Outro bom exemplo de abuso de biblioteca é esperar que o elemento chamado retorne informações confiáveis de DNS ao responsável pela chamada. Nesse caso, o responsável pela chamada abusa a API do elemento chamado ao fazer certas suposições sobre seu comportamento (isto é, que o valor de retorno pode ser usado para fins de autenticação). A outra parte também pode violar o contrato entre quem chama e o que se chama. Por exemplo, se um programador definir SecureRandom como subclasse e retornar um valor não aleatório, o contrato será violado.
Equals()
é chamado em um objeto que não implementa Equals()
.Equals()
em uma classe (ou qualquer superclasse/interface) que não implemente Equals()
explicitamente resulta em uma chamada para o método Equals()
herdada de System.Object
. Em vez de comparar campos membros de objetos ou outras propriedades, o Object.Equals()
compara duas instâncias de objeto para ver se elas são iguais. Embora existam usos legítimos de Object.Equals()
, muitas vezes isso é uma indicação de um código com bug.
public class AccountGroup
{
private int gid;
public int Gid
{
get { return gid; }
set { gid = value; }
}
}
...
public class CompareGroup
{
public bool compareGroups(AccountGroup group1, AccountGroup group2)
{
return group1.Equals(group2); //Equals() is not implemented in AccountGroup
}
}
equals()
é chamado em um objeto que não implementa equals()
.equals()
em uma classe (ou qualquer superclasse/interface) que não implemente equals()
explicitamente resulta em uma chamada para o método equals()
herdada de java.lang.Object
. Em vez de comparar campos membros de objetos ou outras propriedades, o Object.equals()
compara duas instâncias de objeto para ver se elas são iguais. Embora existam usos legítimos de Object.equals()
, muitas vezes isso é uma indicação de um código com bug.
public class AccountGroup
{
private int gid;
public int getGid()
{
return gid;
}
public void setGid(int newGid)
{
gid = newGid;
}
}
...
public class CompareGroup
{
public boolean compareGroups(AccountGroup group1, AccountGroup group2)
{
return group1.equals(group2); //equals() is not implemented in AccountGroup
}
}
finalize()
deve chamar super.finalize()
.finalize()
chamar super.finalize()
[1].super.finalize()
.
protected void finalize() {
discardNative();
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
private void readObjectNoData() throws ObjectStreamException;
getWriter()
depois de chamar getOutputStream
, ou vice-versa.HttpServletRequest
, redirecionar uma HttpServletResponse
ou descarregar o fluxo de saída do servlet faz com que o fluxo associado seja confirmado. Quaisquer redefinições de buffer ou confirmações de fluxo subsequentes, como descarregamentos ou redirecionamentos adicionais, resultarão em IllegalStateException
s.ServletOutputStream
ou PrintWriter
, mas não ambos. Chamar getWriter()
depois de ter chamado getOutputStream()
, ou vice-versa, também causará uma IllegalStateException
.IllegalStateException
impede que o manipulador de resposta seja executado até sua conclusão, eliminando eficientemente a resposta. Isso pode causar instabilidade no servidor, o que é um sinal de um servlet inadequadamente aplicado.Exemplo 2: Por outro lado, o código a seguir tenta gravar e descarregar o buffer de
public class RedirectServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
...
OutputStream out = res.getOutputStream();
...
// flushes, and thereby commits, the output stream
out.flush();
out.close(); // redirecting the response causes an IllegalStateException
res.sendRedirect("http://www.acme.com");
}
}
PrintWriter
depois que a solicitação foi encaminhada.
public class FlushServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
...
// forwards the request, implicitly committing the stream
getServletConfig().getServletContext().getRequestDispatcher("/jsp/boom.jsp").forward(req, res);
...
// IllegalStateException; cannot redirect after forwarding
res.sendRedirect("http://www.acme.com/jsp/boomboom.jsp");
PrintWriter out = res.getWriter();
// writing to an already-committed stream will not cause an exception,
// but will not apply these changes to the final output, either
out.print("Writing here does nothing");
// IllegalStateException; cannot flush a response's buffer after forwarding the request
out.flush();
out.close();
}
}
Content-Length
é definido como negativo.Content-Length
de um pedido indica que um programador está interessado na0
ou umContent-Length
incorreto.
URL url = nova URL("http://www.exemplo.com");
HttpURLConnection huc = (HttpURLConnection)url.openConnection();
huc.setRequestProperty("Content-Length", "-1000");
Content-Length
é definido como negativo.Content-Length
de uma solicitação indica que um programador está interessado na0
ou umContent-Length
incorretamente como negativo:
xhr.setRequestHeader("Content-Length", "-1000");
ToString()
é chamado em um array.ToString()
em um array indica que um desenvolvedor está interessado em retornar o conteúdo do array como um String. No entanto, uma chamada direta para ToString()
em um array retornará um valor de cadeia de caracteres contendo o tipo do array.System.String[]
.
String[] stringArray = { "element 1", "element 2", "element 3", "element 4" };
System.Diagnostics.Debug.WriteLine(stringArray.ToString());
toString()
é chamado em um array.toString()
em um array indica que um desenvolvedor está interessado em retornar o conteúdo do array como um String. No entanto, uma chamada direta para toString()
em um array retornará um valor de string contendo o tipo do array e o código hash na memória.[Ljava.lang.String;@1232121
.
String[] strList = new String[5];
...
System.out.println(strList);