1. Java / Говнокод #25392

    +3

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    /*
     * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     *
     * This code is free software; you can redistribute it and/or modify it
     * under the terms of the GNU General Public License version 2 only, as
     * published by the Free Software Foundation.
     *
     * This code is distributed in the hope that it will be useful, but WITHOUT
     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     * version 2 for more details (a copy is included in the LICENSE file that
     * accompanied this code).
     *
     * You should have received a copy of the GNU General Public License version
     * 2 along with this work; if not, write to the Free Software Foundation,
     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     *
     * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     * or visit www.oracle.com if you need additional information or have any
     * questions.
     */
    
    /* @test
       @bug 4890726
       @summary Check the correctness of KOI8_U by comparing to KOI8_R
     */
    
    import java.util.*;
    import static java.lang.Character.UnicodeBlock;
    
    public class UkrainianIsNotRussian {
        private static String decode(byte[] bytes, String encoding) throws Throwable {
            String s = new String(bytes, encoding);
            equal(s.length(), 1);
            check(Arrays.equals(s.getBytes(encoding), bytes));
            return s;
        }
    
        private static void realMain(String[] args) throws Throwable {
            final byte[] bytes = new byte[1];
            int differences = 0;
            for (int i = 0; i < 0xff; i++) {
                bytes[0] = (byte) i;
                final String r = decode(bytes, "KOI8_R");
                final String u = decode(bytes, "KOI8_U");
                if (! r.equals(u)) {
                    differences++;
                    final char rc = r.charAt(0);
                    final char uc = u.charAt(0);
                    final UnicodeBlock rcb = UnicodeBlock.of(rc);
                    final UnicodeBlock ucb = UnicodeBlock.of(uc);
                    System.out.printf("%02x => %04x %s, %04x %s%n",
                                      i, (int) rc, rcb, (int) uc, ucb);
                    check(rcb == UnicodeBlock.BOX_DRAWING &&
                          ucb == UnicodeBlock.CYRILLIC);
                }
            }
            equal(differences, 8);
        }
    
        //--------------------- Infrastructure ---------------------------
        static volatile int passed = 0, failed = 0;
        static void pass() {passed++;}
        static void fail() {failed++; Thread.dumpStack();}
        static void fail(String msg) {System.out.println(msg); fail();}
        static void unexpected(Throwable t) {failed++; t.printStackTrace();}
        static void check(boolean cond) {if (cond) pass(); else fail();}
        static void equal(Object x, Object y) {
            if (x == null ? y == null : x.equals(y)) pass();
            else fail(x + " not equal to " + y);}
        public static void main(String[] args) throws Throwable {
            try {realMain(args);} catch (Throwable t) {unexpected(t);}
            System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
            if (failed > 0) throw new AssertionError("Some tests failed");}
    }

    https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/test/jdk/sun/nio/cs/UkrainianIsNotRussian.java

    Запостил: j123123, 21 Февраля 2019

    Комментарии (159) RSS

    • Где бы этот «bug 4890726» почитать… Там явно есть что-то интересненькое.
      Ответить
      • https://bugs.openjdk.java.net/browse/JDK-4890726
        Ответить
        • Никакой багор (((
          Ответить
        • Значит, «KOI8-U» в «JDK» включить забыли, а в «KOI8-R» нет букв «ґ», «є», «ї», «і».

          А в 2019-м году в «Java» кто-нибудь пользуется восьмибитными кодировками?
          Ответить
          • показать все, что скрытоvanished
            Ответить
            • Поди ещё на «Микроше» и на «Корвете» не запустится.
              Ответить
              • показать все, что скрытоvanished
                Ответить
                • Судя по тому, что некоторые программы на «Винде» и сейчас нежелательно устанавливать в директорию, имя которой содержит нелатинские символы, привычка всё делать по старым мануалам не ограничивается «Линуксом» и 2003-м годом.

                  Был почтовый сервис http://е-письмо.рф/ –— не взлетел. С таким ящиком нельзя было зарегистрироваться на форумах ни как вася@е-письмо.рф, ни как %D0%B2%D0%B0%D1%81%D1%[email protected]. А всё потому, что кто-то всё делает по старым мануалам.
                  Ответить
                  • показать все, что скрытоvanished
                    Ответить
                  • показать все, что скрытоvanished
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                    • Я спотыкался о русские символы в русской винде. Уже не помню, что за софт такой был.
                      Ответить
                      • показать все, что скрытоvanished
                        Ответить
                        • показать все, что скрытоvanished
                          Ответить
                          • показать все, что скрытоvanished
                            Ответить
                            • В некотором софте проблема была, даже если на чужую винду не переносить. В старых версиях «Delphi» файловые функции зачем-то по поводу и без повода гоняли функции OemToAnsi и AnsiToOem, которые на русской Винде переводили из 1251 в 866 и обратно. Т. е. программист отправлял имя в правильной кодировке, а библиотека «Delphi» его ещё раз перекодировала.
                              Ответить
                              • показать все, что скрытоvanished
                                Ответить
                                • Я уже не помню. Вероятно, разработчики библиотеки предполагали, что ты исходник будешь набирать в досовском редакторе (например, в синенькой IDE на «Turbo Vision»), поэтому он у тебя будет в 866 (OEM), а не в 1251 (ANSI). Хотя в то же время сами для формошлёпства наклепали гуёвую IDE, которая сохраняет в 1251 (ANSI).

                                  Похоже, что новую IDE и библиотеку делали разные отделы.
                                  Ответить
                        • В FAT (12/16/32) для каждого файла в каталоге создавались две записи: одна в формате DOS (8.3, cp866), другая в формате VFAT (длинное имя, кодировка UCS-2 или UTF-16, т. е. юникодное).

                          Винда смотрела досовскую запись, только если длинное имя отсутствовало или было запорото.
                          Ответить
                          • показать все, что скрытоvanished
                            Ответить
                            • Смотри пример: у одной директории есть имена «Program Files» (в юникоде) и «PROGRA~1» (в кодировке 866); у другой «Мои документы» (в юникоде) и «МОИДОК~1» (в кодировке 866).

                              Если бы функция «с A на конце» не умела читать юникодные имена, она не смогла бы обработать запросы к «Program Files» и к «Мои документы». Внутри функциям «с A на конце» приходилось совершать нелепую операцию: расширять входную строку в локальной кодировке до юникода (возможно, это расширение происходило где-то в недрах драйвера файловой системы).
                              Ответить
                              • P.S. Ну а FindFirstFileA приходилось наоборот найденное имя зожимать до локальной кодировки.
                                Ответить
                              • показать все, что скрытоvanished
                                Ответить
                                • Внешне оно работало примерно одинаково и в «Windows 95», и в «Windows NT». Где именно происходило преобразование, интересно только писателям драйверов файловых систем. Кстати, был неофициальный драйвер ext2.vxd. Если его кинуть в соответствующую директорию «Windows 95», он автоматически монтировал разделы ext2. Значит, как минимум, его писатели знали, как всё работает.

                                  *****

                                  Представь себе, что ты по ошибке создал директорию «Цыплёнок» и хочешь переименовать её в «Индюшонок». Вызываешь MoveFileA("Цыплёнок", "Индюшонок");

                                  Что будет дальше? Мои догадки:
                                  1. "Цыплёнок" из 1251 будет преобразована в Unicode.
                                  2. Драйвер будет искать "Цыплёнок" в Unicode.
                                  3. Если не найдёт (например, директория была создана в голом DOS), преобразует в 866 и будет искать "ЦЫПЛЁНОК" (хотя он и в предыдущем пункте будет искать так же, ибо в Винде файлы регистронезависимы).
                                  4. Теперь нужно переименовать. Второй аргумент ("Индюшонок") будет преобразован из 1251 в Unicode.
                                  5. Длинное имя будет заменено на "Индюшонок". Если его не было (директория была создана в голом DOS), оно будет создано.
                                  6. Для совместимости с DOS нужно обновить и короткое имя. "Индюшонок" будет преобразовано в 866, затем в верхний регистр. Если не влезло в 8 символов или есть символы, запрещённые в DOS, имя будет усечено с добавлением тильды и произвольного числа для предупреждения коллизий. В данном случае нужно будет записать "ИНДЮШО~1".

                                  Windows NT, в отличие от 95, уже не всегда генерирует осмысленные короткие имена. Вместо "ИНДЮШО~1" она может сгенерировать "65A8FC~1". Какой багор)))
                                  Ответить
                                  • P.S. Итого простая операция MoveFileA выполняла следующие преобразования:
                                    1. Первый аргумент 1251→Unicode.
                                    2. Опционально Unicode→866 (если длинное имя не найдено).
                                    3. Второй аргумент 1251→Unicode.
                                    4. Unicode→866 (для генерации короткого имени).

                                    Функция MoveFileW тратила меньше сил, ибо аргументы уже были в Unicode.
                                    Ответить
                                    • В моей Win10 x64 MoveFileA() вызывает MoveFileWithProgressTransactedA(), в которой для обоих аргументов вызывается Basep8BitStringToDynamicUnicodeString(), после чего управление передаётся в MoveFileWithProgressTransactedW(), в которой и происходят всякая питушня (в частности, для имён файлов вызывается RtlDosPathNameToNtPathName_U(), а после некоторой обработки происходит само перемещение обычной связкой BasepCopyFileExW() — DeleteFileW()).
                                      Ответить
                                  • показать все, что скрытоvanished
                                    Ответить
                                    • >> Слушай, ну что MoveFile что MoveFileA все равно под капотом вызовет NtCreateFile

                                      >> А тот получит ObjectAttributes с полем
                                      PUNICODE_STRING ObjectName

                                      На NT понятно. Но самое смешное, что в «Windows 95» была та же семантика, хотя никакого ntoskrnl не было.
                                      Ответить
                                    • >> он поищет сначала Цыплёнок(двбайтовый) а потом ЦИПЛЁН~1 в однобайтовой кодировке

                                      Неверно. Он сначала поищет Цыплёнок (двубайтовый), а потом ЦЫПЛЁНОК в однобайтовой кодировке.

                                      ЦЫПЛЁН~1 он искать НЕ будет, если мы явно именно так с тильдой не попросим найти.

                                      *****

                                      С этим связан прикол. В реестре путь к «Program Files» в некоторых местах прописан как «C:\Program Files», а в некоторых как «C:\PROGRA~1». В свежеустановленной винде обычно они соответствуют одной и той же директории, поэтому никаких проблем юзер не замечает.

                                      Сценарий диверсии:
                                      1. Временно переименовываем «Program Files» в «Pituh».
                                      2. Создаём «C:\Programms». В 8 символов не уложились, поэтому создастся короткое имя «C:\PROGRA~1» (других директорий, начинающихся на «PROGRA» сейчас в корне нет, поэтому будет единичка).
                                      3. Переименовываем «Pituh» обратно в «Program Files». Поскольку «PROGRA~1» уже занято, будет создано короткое имя «PROGRA~2».
                                      4. Итог: «PROGRA~2» связано с «Program Files», а «PROGRA~1» связано с другой директорией.

                                      Теперь у нас «PROGRA~1» и «Program Files» соответствуют разным директориям.
                                      Ответить
                                      • > В реестре путь к «Program Files» в некоторых местах прописан как «C:\Program Files», а в некоторых как «C:\PROGRA~1».
                                        Какой же адский багор. Уже много лет Microsoft ратуют за использование «SHGetKnownFolderPath()», а сами продолжают хардкодить пути в сраном «8.3», сдохшем задолго до рождения многих современных программистов?
                                        Ответить
                                        • SHGetKnownFolderPath можно использовать не везде. В некоторых местах нужно указывать полный путь (да, можно создать значение типа REG_EXPAND_SZ, но тогда придётся предварительно заносить имена общеизвестных папок в переменные окружения, чтобы было что подставлять).

                                          «MS Office» и адобовские продукты любят срать в реестр путями в формате «8.3». Ещё инсталяторы зачастую прописывают пути к деинсталяторам в таком же формате.
                                          Ответить
                                          • > но тогда придётся предварительно заносить имена общеизвестных папок в переменные окружения
                                            Ну, всякие %ProgramFiles, %AppData%, %SystemRoot%, %Temp% и им подобные вроде как уже сто лет в винде существуют.

                                            > «MS Office» и адобовские продукты любят срать в реестр путями в формате «8.3». Ещё инсталяторы зачастую прописывают пути к деинсталяторам в таком же формате.
                                            Печально всё это.
                                            Ответить
                                  • Глянь, какой багор ))):
                                    https://blogs.msdn.microsoft.com/arvindsh/2013/06/19/debugging-story-slowness-due-to-ntfs-short-file-8-3-name-generation/

                                    И вот оттуда ссылка:
                                    https://support.microsoft.com/en-us/help/121007/how-to-disable-8-3-file-name-creation-on-ntfs-partitions
                                    Ответить
                                    • показать все, что скрытоvanished
                                      Ответить
                                    • показать все, что скрытоvanished
                                      Ответить
                                      • На съёмных носителях короткие имена (в формате 8.3) генерировали в целях совместимости со старыми ОС, однако, дискеты были в формате FAT12, флешки –— в форматах FAT16 (до 2...4 ГБ) и FAT32 (до 32 ГБ). В NTFS дискеты и флешки никто не форматировал.

                                        Допустим, на картах памяти с файловой системой FAT короткие имена нужны, чтобы их видел фотоаппарат или плеер.

                                        На NTFS короткие имена могли быть задействованы в следующих случаях:

                                        1. Досовской программой, запущенной из-под NTVDM. Сейчас неактуально, поскольку в 64-битных виндах нет NTVDM (неофициальный проект NTVDM64 сейчас не рассматриваем).

                                        2. Досовской программой, запущенной через эмулятор (DOSBOX и всякие виртуалки). Однако, в этом случае генератор коротких имён можно встроить в сам эмулятор. Нет никакой нужды поддерживать его системой.

                                        3. DOS'ом через неофициальный драйвер NTFS. Однако, и в этом случае генератор коротких имён можно встроить в драйвер.

                                        И правда, на NTFS генерировать короткие имена сейчас нет смысла. Разве что ради всякого говна, которое любит прописываться в C:\PROGRA~1, но на этот случай можно сделать симлинк (или directory join).
                                        Ответить
                            • Ты теперь представляешь, что такое «Windows 95»? С одной стороны, апгрейд FAT до юникодных имён файлов, юникодные шрифты, «Офис 97» с юникодным текстом. С другой стороны, функции с A на конце.
                              Ответить
                      • у меня помню какой-то дельфи-говнософт на винде не работал, если там десятичный разделитель выставлен как ","
                        а если выставить "." то работает
                        Ответить
                        • В более "продвинутом" говнософте обычно заменяли точки на сепаратор из локали.

                          З.Ы. Kerbal Space Program падал на линупсах с аналогичной ошибкой. Так что и на C# на те же самые грабли с локалями наступают...
                          Ответить
                        • Я против использования "," как "десятичного разделителя", "," —– это разделитель элементов в списке.
                          Ответить
                          • Помню как преподы, чтобы как-то убрать эту неоднозначнось, писали запятые разного размера. (на доске или в тетради)
                            Ответить
                            • Это уже как какая-то типографика из школы дизайнеров. Как с чёрточками: дефис, символ переноса, разделитель в номере телефона, минус, короткое тире, длинное тире, ещё 100500 питушарских символов, которые на практике всё равно перепутают.
                              Ответить
                          • Полностью поддерживаю.
                            Ответить
                          • А мне нравится. Только тогда нужен такой синтаксис списков, чтобы не путать. Например, разделять элементы списка точкой с запятой или придумать что-нибудь со скобками.
                            Ответить
                            • > нужен такой синтаксис списков, чтобы не путать
                              Например в '(LISP) {TCL} и [Red] вообще нет разделителей, всё пишется через пробелы.

                              В "Red" кстати можно использовать в дробях и "," и ".", а ещё в нём 3 или более числа разделённых точкой —– это кортеж (с запятыми, почему-то, такого нет). Кстати, в {Red} полно разных 'литералов на все случаи жизни:
                              Red []
                              
                              write %red-literals.html read/binary https://tio.run/##[email protected]@[email protected]@jcZNi5CSuEEY7wSUivAdrwHE856/[email protected]@ONs/X8QU7DQUgF9X/[email protected]zBTsIsL8/[email protected]/YYvW7EB9cZ3Aweu4NbixOqzdv2Lao3bYf
                              
                              a: [
                                42
                                3.1415
                                2,7182
                                2.6.5
                                127.0.0.1
                                255.255.255.255.255
                                word
                                :get-word
                                set-word:
                                'lit-word
                                "string"
                                {string}
                                #"C"
                                (paren)
                                [block]
                                this/is/path
                                %../../../etc/passwd
                                http://govnokod.ru/
                                [email protected]
                                00:30:00
                                13-09-2019
                              ]
                              
                              foreach i a [
                                probe reduce [i type? i]
                              ]
                              Ответить
                          • показать все, что скрытоvanished
                            Ответить
                            • > если ты низкоуровневый то ты говоришь не про то
                              Я хотел пиздеть про осемблеры, форты, сишки, но как зарегал файку почему-то всё прошло.

                              > То-есть сломать железо из витуалки никак нельзя?
                              Ну не зря же виртуалки придумали. Хотя, может быть и можно, но Крис умир, а борманд молчит,не у кого спросить.

                              А вообще-то я своим петушиным моском нихуя не понял, что ты нопейсал. Что делает Вирт у Аллки?
                              Ответить
                            • Сброс множителя от перегрева, емнип, аппаратный и не отключается. Так что и с хоста не сломаешь. Разве что повесишь.
                              Ответить
    • показать все, что скрытоvanished
      Ответить
      • Простите?
        Ответить
      • Не кокококомпилируется:
        https://ideone.com/aTABMJ

        Оператор "-" для строк в «Java» не определён, а перегрузки операторов в этом языке нет.
        Ответить
        • показать все, что скрытоvanished
          Ответить
        • #include <stdio.h>
          
          int main(void)
          {
              puts("Путин" - "хуйло");
              return 0;
          }
          Segmentation fault.

          Я не понял, мой конплукхтер за Путена? То ли дело "DOS".
          Ответить
        • Если не рассматривать морально-политические аспекты, у автора было два идентификатора, а не две строки. Соответственно, если это числа, то минус вполне оправдан. Вот с восклицательным знаком будет проблема.
          А если считать, что это строки, то можно вообще всё в строку записать и радоваться.
          system.out.println("Миру - мир!") - и ни минус, ни восклицательный знак не мешают.
          Ответить
    • equal(differences, 8);

      Константа Сёмы.
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий