Esapi и использование replaceAll для пустых строк

Я видел ссылку на использование String.replaceAll("",""); как некоторые средства для удаления "пустых" или "непечатаемых символов" из строки в Java. Это неверно, поскольку ответ продемонстрирует.

value = value.replaceAll("", "");

1 ответ

Решение

Используя Junit, я проверяю каждый символ Unicode, от \u0000 до \uffff.

@Test
public void testReplaceBlanks(){
char input = 0;
char escape = '\u0000';

for(char i = 0; i <= 65535; ++i){
    input = (char) (escape + i);
    System.out.print(input);
    System.out.print(" ");
    if( i % 80 == 0){
        System.out.println();
    }

    String test = new String(Character.toString(input));
    assertTrue(!"".equals(test.replaceAll("", "")));

    if(i == 65535)
        break;
}
}

Я не нахожу ни одного случая, когда эта строка кода делает что-нибудь полезное.

Поскольку я обнаружил эту проблему еще пару раз в Интернете, вот более надежный тестовый пример:

Главная проблема здесь, эта строка кода - НЕТ-ОП.

value = value.replaceAll ("", "");

Рассмотрим следующий тестовый пример:

  public static void println(String s) {
    System.out.println(s);
  }

  @Test
  public void testNullStripWithEmptyString() {
    String input = "foo" + '\0';
    String input2 = "foo";
    println(input);
    println("input:");
    printBytes(input.getBytes());
    println("input2:");
    printBytes(input2.getBytes());
    String testValue = input.replaceAll("", "");
    println("testValue:");
    printBytes(testValue.getBytes());
    String testvalue2 = input2.replaceAll("","");
    println("testvalue2");
    printBytes(testvalue2.getBytes());
    assertFalse(input.equals(input2));
    assertFalse(testValue.equals(testvalue2));
  }

Этот тестовый пример демонстрирует, во-первых, что в байтовых представлениях двух входных строк нулевой байт появляется в первом, а не во втором. Затем мы переходим к вызову *.replaceAll("", ""); и сохраните значения в две новые переменные, testValue и testvalue2.

Затем это приводит к первому утверждению, которое утверждает, что два значения не должны быть равными, вызывая обычный метод String equals. Это тривиально верно, потому что у нас действительно есть непечатаемый нулевой байт, добавленный к строке. Однако гвоздь в гробу состоит в том, чтобы продемонстрировать, что это условие все еще выполняется после вызова *.replaceAll("", ""); на две строки testValue.

Единственный способ предотвратить непечатные байты или байты NULL - это реализовать следующий тестовый пример:

  @Test 
  public void testNullStripWithNullUnicodeEscape(){
    String input = "foo" + '\0';
    String input2 = "foo";
    println(input);
    println("input:");
    printBytes(input.getBytes());
    println("input2:");
    printBytes(input2.getBytes());
    String testValue = input.replaceAll("\u0000", "");
    println("testValue:");
    printBytes(testValue.getBytes());
    String testvalue2 = input2.replaceAll("\u0000","");
    println("testvalue2");
    printBytes(testvalue2.getBytes());
    assertFalse(input.equals(input2));
    assertTrue(testValue.equals(testvalue2));
  }
Другие вопросы по тегам