java.lang.StringIndexOutOfBoundsException: String index out of range: -5

Alguém sabe me dizer onde está o erro ? Já tentei de tudo, fiz várias mudanças mas não consigo achar o erro, quando rodo dá o seguinte erro:

java.lang.StringIndexOutOfBoundsException: String index out of range: -5
at java.lang.AbstractStringBuilder.substring(AbstractStringBuilder.java:935)
	at java.lang.StringBuffer.substring(StringBuffer.java:480)
	at Updater.Main_Gui.getDownloadLinkFromHost(Main_Gui.java:261)
	at Updater.Main_Gui.access$100(Main_Gui.java:37)
	at Updater.Main_Gui$3.run(Main_Gui.java:107)

O código é:

private void downloadFile(String link) throws MalformedURLException, IOException
    {
        URL url = new URL(link);
        URLConnection conn = url.openConnection();
        InputStream is = conn.getInputStream();
        long max = conn.getContentLength();
        outText.setText(outText.getText()+"\n"+"Baixando arquivos...\nTamanho da atualização(comprimida): "+max+" Bytes");
        BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(new File("Conchazip")));
        byte[] buffer = new byte[32 * 1024];
        int bytesRead = 0;
        int in = 0;
        while ((bytesRead = is.read(buffer)) != -1) {
            in += bytesRead;
            fOut.write(buffer, 0, bytesRead);
        }
        fOut.flush();
        fOut.close();
        is.close();
        outText.setText(outText.getText()+"\nDownload Completado!");
    }

private String getDownloadLinkFromHost() throws MalformedURLException, IOException
{
    String path = "http://site_do_meu_download/4f9981df-27cb-4f6d-9465-8a6f9318fa76.zip";
    URL url = new URL(path);

    InputStream html = null;

    html = url.openStream();

    int c = 0;
    StringBuilder buffer = new StringBuilder("");

    while(c != -1) {
        c = html.read();
    buffer.append((char)c);

    }
    return buffer.substring(buffer.indexOf("[url]")+5,buffer.indexOf("[/url]"));
}

O que há na linha 261?

Segundo a Documentação:

Exceção lançada pelos métodos String para indicar que um índice é negativo ou maior que o tamanho da string. Para alguns métodos, como o método charAt, essa exceção também é lançada quando o índice é igual ao tamanho da string.

na linha 261 está esse código:

return buffer.substring(buffer.indexOf("")+5,buffer.indexOf(""));

Eu tentei mexer onde tem o +5 mas nada do que coloquei funcionou.

Traduzindo: “Retorne a substring do buffer, começando pelo índice onde for igual a [url] acrescido de 5 e terminando onde o índice de for igual a [/url] menos 1”.

Tendo em vista o código:
return buffer.substring(buffer.indexOf("[url]")+5,buffer.indexOf("[/url]"));
e recorrendo a documentação:

1 - public int indexOf(String str):

Retorna o índice dentro dessa sequência da primeira ocorrência da subseqüência especificada.

Logo, é de se esperar que ele ele retorne o valor do índice i onde a string [url] aparece pela primeira vez. Caso não encontre, ele retorna -1. Como você adicionou cinco ao índice, ele deveria encontrar i + 5.

2 - public String substring(int start, int end):

Retorna um novo String que contém uma subsequência de caracteres contidos atualmente nesta seqüência. A subseqüência começa no início especificado e se estende ao caractere no final do índice - 1.

Tem certeza que essas substrings estão na string original? Se não ele irá retornar -1, porque a documentação (Doc) indica:

Throws: StringIndexOutOfBoundsException - se start ou end forem negativos ou maiores que length (), ou start for maior que end.

Mas onde isso entra no trecho? :

return buffer.substring(buffer.indexOf("")+5,buffer.indexOf(""));

Porque no StringBuilder já está tudo ok.

/**
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
@Override
public StringBuilder append(CharSequence s, int start, int end) {
super.append(s, start, end);
return this;

Consegui resolver da seguinte forma:

URL url = new URL(“https://site…/…/Concha.zip”);
File file = new File(“C:\temp\Concha.zip”);
FileUtils.copyURLToFile(url, file);

    URLConnection conn = url.openConnection();
    InputStream is = conn.getInputStream();

    long max = conn.getContentLength();
    outText.setText(outText.getText()+"\n"+"Baixando arquivos...\nTamanho da atualização(comprimida): "+max+" Bytes");
    BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(new File("Concha.zip")));
    byte[] buffer = new byte[32 * 1024];

    int bytesRead;
    int in = 0;
    while ((bytesRead = is.read(buffer)) != -1) {
        in += bytesRead;
        fOut.write(buffer, 0, bytesRead);
    }
    fOut.flush();
    fOut.close();
    
    outText.setText(outText.getText()+"\nDownload Completado!");