1. Си / Говнокод #23348

    +2

    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
    // https://github.com/vk-com/kphp-kdb/blob/ce6dead5b3345f4b38487cc9e45d55ced3dd7139/bayes/bayes-data.c#L569
      for (i = j = 0; v[i]; i++) {
        f[j] = i;
        if (v[i + 1] == '#' && (v[i] == '&' || v[i] == '$')) {
          int r = 0, ti = i;
          if (v[i + 2] != 'x') {
            for (i += 2; v[i] != ';' && v[i]; i++) {
              if ('0' <= v[i] && v[i] <= '9') {
                r = r * 10 + v[i] - '0';
              } else {
                break;
              }
            }
          } else {
            for (i += 3; v[i] != ';' && v[i]; i++) {
              if (('0' <= v[i] && v[i] <= '9') ||
                  ('a' <= v[i] && v[i] <= 'f') ||
                  ('A' <= v[i] && v[i] <= 'F')) {
                r = r * 16;
                if (v[i] <= '9') {
                  r += v[i] - '0';
                } else if (v[i] <= 'F') {
                  r += v[i] - 'A' + 10;
                } else {
                  r += v[i] - 'a' + 10;
                }
              } else {
                break;
              }
            }
          }
          if (r == 0) {
            bad[j] = 0;
            pv[j++] = v[i = ti];
          } else {
            bad[j] = 1;
            pv[j++] = r;
            if (v[i] != ';') {
              i--;
            }
          }
        } else if (v[i] == '%' && '0' <= v[i + 1] && v[i + 1] <= '7' &&
                                (('0' <= v[i + 2] && v[i + 2] <= '9') ||
                                 ('a' <= v[i + 2] && v[i + 2] <= 'f') ||
                                 ('A' <= v[i + 2] && v[i + 2] <= 'F'))) {
          int r = (v[i + 1] - '0') * 16;
          if (v[i + 2] <= '9') {
            r += v[i + 2] - '0';
          } else if (v[i + 2] <= 'F') {
            r += v[i + 2] - 'A' + 10;
          } else {
            r += v[i + 2] - 'a' + 10;
          }
          i += 2;
          if (r != ':' && r != '/' && r != '=' && r != '?' && r != '&' && r != '+') {
            bad[j] = 1;
          } else {
            bad[j] = 0;
          }
          pv[j++] = r;
        } else {
          bad[j] = 0;
          pv[j++] = v[i];
        }
      }
      f[j] = i;
      pv[j] = 0;
    
      for (i = 0; i < j; i++) {
        if ('A' <= pv[i] && pv[i] <= 'Z') {
          pv[i] = pv[i] - 'A' + 'a';
          bad[i] += 2;
        }
      }

    Очередной ебаный пиздец из kPHP
    В предыдущих сериях:
    http://govnokod.ru/19842
    http://govnokod.ru/15406

    Запостил: j123123, 22 Сентября 2017

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

    • Взгляните например на вот этот вот пиздец (я его откомментировал):
      int rbad = 0, n;
      for (i = 0; pv[i]; i++) {
        // вот тут проверяем что в начале идет "http" кусок
        if (pv[i] == 'h' && pv[i + 1] == 't' && pv[i + 2] == 't' && pv[i + 3] == 'p') {
          // какая-то ебучая add переменная
          int add = 0;
          if (pv[i + 4] == 's') {
            // которая будет равна 1 если у нас https, ну это чтоб ебаное смещение правильно учитывать
            // "https" на один байтик длинней, чем "http" 
            add = 1; 
          }
          // дальше проверяем остальной кусок урла, тут вот например видно, что если https урл
          // то тогда это говно начинает проверять с адреса на одну единицу больше
          // в этом блядском говне проверяется кусок "://" который должен идти после http(s)
          if (pv[i + 4 + add] == ':' && pv[i + 5 + add] == '/' && pv[i + 6 + add] == '/') {
            // это цикл, в котором тупо прокручивается кусок, отвечающий за доменное имя
            // т.е. по pv[j] будет конец доменного имени
            for (j = i + 7 + add; is_domain_symbol (pv[j]); j++) ;
            // если нихрена прокручено не было, то continue...
            // т.е. бля, на следующей итерации это блядское говно будет пытаться заматчить
            // эту сраную http(s):// парашу уже начиная не с pv[0], а с pv[1]
            if (j == i + 7 + add) {
              continue;
            }
            // это оно проверяет порт после доменного имени, т.е. "https://example.org:8080"
            if (pv[j] == ':') {
              j++;
              while ('0' <= pv[j] && pv[j] <= '9') {
                j++;
              }
            }
      ...

      Как думаете, сраные вконтактовские долбоебы-олимпиадники, писавшие эту хуйню, слышали например про алгоритм Ахо-Корасик или Бойера-Мура?
      Ответить
      • > слышали например про алгоритм Ахо-Корасик или Бойера-Мура?

        Я думаю, что они слышали. А ты слышал?

        Бойер-Мур и Ахо-Корасик строят автоматы для поиска одного или нескольких (в случае А-К) шаблонов в строке. Т.е. по сути это реализация find(needle(s), haystack). Как это поможет тебе для парсинга урла в один проход?
        Ответить
        • Ну смотри, надо заматчить "http://" и "https://" Очевидно, что в качестве шаблона отлично подойдет "http??/", где "?" это неважно какой символ:
          http://
          https://
          http??/

          После заматчивания подобной хрени, можно в "?" проверить, было ли там "http://" или "https://" или вообще некая иная хрень, и дальше или пытаться это парсить дальше как урл, или искать в другом месте начало урла
          Ответить
          • > Ну смотри, надо заматчить "http://" и "https://"

            Т.е. ты предлагаешь строить по отдельному автомату только для того, чтобы заматчить каждый компонент урла?
            Типа это будет быстрее/лучше, чем последовательность рукописных автоматов на сишке?
            Или нужно снова автоматы из сишных комментариев генерить? Или семантику описывать на Coq с кодогенератором?

            Код может и не идеальный, но идеологически против такого подхода я против ничего не имею. Кмк, оптимальный трейдофф в плане speed/running time/development time. Это скорее ты упоротый, а не вк-олимпиадники.
            Ответить
            • >Кмк, оптимальный трейдофф в плане speed/running time/development time.

              Нет, не оптимальный. Этот код кстати довольно легко можно затормозить, подсунув какие-нибудь специальные входные говноданные, типа
              http://http://http://http://http://http://http://http://http:// и т.д.

              т.е. если подобный говнокод выполняется где-то на бэкенде и кто-то без капчи и регистрации может туда отправлять текстовые данные, которые через такое говно прокручиваются, можно запросто заDDoSить, отправляя кучу таких дебильных строк
              Ответить
              • Кстати я думаю можно даже хитрее поступить, например максимально пытаться заставить обосраться предсказатель переходов в интеловском говнопроцессоре, типа нагеренировать какого-то такого пиздеца
                hhhttphthttps:htthtttthttthttps://http.http:1234http://ht.http://http.http:666http
                Ответить
        • Вообще тут можно довольно эффективную эвристику придумать, например проверять некий символ на то, что в нем нет никаких символов, которые есть в "https://"

          например, проверяя символ в позиции
                 ?
           hui pizda jigurda govno lorem ipsum http://govnokod.ru/
          
          на 'h' 't' 'p' 's' ':' '/' (такая проверка очень быстрой будет, если через таблицу поиска)
          и не найдя совпадений, мы тут отечем сразу кучу вариантов
          и не нужно будет продрачивать последовательно по байтику эту сраную строку,
          можно смело шагать по ней широкими шагами
          
                 ?
           hui pizda jigurda govno lorem ipsum http://govnokod.ru/
           https://      |
           http://       |
            https://     |
            http://      |
             https://    |
             http://     |
              https://   | то, сколько вариантов мы отсекаем
              http://    |
               https://  |
               http://   |
                https:// |
                http://  |
                 https://|
                 http:// |
                         V
          И теперь аналогичную говнопроверку можно сделать вот в этой позиции
                         ?
           hui pizda jigurda govno lorem ipsum http://govnokod.ru/
                   https://      |
                   http://       |
                    https://     |
                    http://      |
                     https://    |
                     http://     |
                      https://   |
                      http://    |
                       https://  |
                       http://   |
                        https:// |
                        http://  |
                         https://|
                         http:// |
                                 V
          ну и так далее, и это будет намного быстрее работать,
          чем то тупое говно, написанное вконтактовыми олимпиадниками
          Ответить
          • Вот, пофиксил слегка
            ?
             hui pizda jigurda govno lorem ipsum http://govnokod.ru/
             https://     |
             http://      |
              https://    |
              http://     |
               https://   |
               http://    |
                https://  |
                http://   |
                 https:// |
                 http://  |
                  https://|
                  http:// |
                   https://
                   http://|
                          ?
                    https://     |
                    http://      |
                     https://    |
                     http://     |
                      https://   |
                      http://    |
                       https://  |
                       http://   |
                        https:// |
                        http://  |
                         https://|
                         http:// |
                          https://
                          http://|
                                 ?
                           https://     |
                           http://      |
                            https://    |
                            http://     |
                             https://   |
                             http://    |
                              https://  |
                              http://   |
                               https:// |
                               http://  |
                                https://|
                                http:// |
                                 https://
                                 http://|
            Ответить
            • зачем? Быстрее пройти uint32_t'ом "http" по массиву пока не встретишь, а остальное уже отдельно обработать "https://" можно фильтровать сразу через uint64_t. Если прям так нужно быстродействие, можно еще simd захреначить (c load_u).
              Ответить
              • Поясни. Ты предлагаешь тупо делать кучу ебаных uint32_t чтений с unaligned memory access и последующих сравнений?
                hui pizda jigurda govno lorem ipsum http://govnokod.ru/
                http
                 http
                  http
                   http
                    http
                ...

                по-твоему это будет быстрее?
                Ответить
                • могу ошибаться, но вроде как в худшем случае так же
                  Ответить
                  • Тут не будет худшего случая. Вряд ли кто-то будет специально вхерачивать какое-то говно, типа
                    httphttphttphttphttphttp

                    чтобы затормозить парсер. Да и тут такой подход будет избыточен. Например
                    httphttphttphttphttphttp
                    http <- ага, вот тут мы заматчили кусок урла
                    пытаемся дальше
                    httphttphttphttphttphttp
                    https:// <- нет
                    http:// <- нет
                    
                    теперь попробуем по новому смещению
                    httphttphttphttphttphttp
                     http  <- вот тут уже полная лажа начинается
                      http <- нет смысла в этих тупых проверках
                    т.к. там уже было провенено и заматчено http
                    и прогонять эти байты смысла нет
                    
                    начинать новую проверку имеет смысл отсюда
                    httphttphttphttphttphttp
                        http

                    в общем даже тупую проверку на совпадение "http" куска можно заоптимизировать
                    Ответить
                    • худший в плане реализации процессора, если не брать совсем говно мамонта. И да: как я уже написал, можно и по 8 байт брать ("https://") или 8, но со сдвигом на 8 ("\0http://")
                      Ответить
          • 3.14159265
            Ответить
      • Ты можешь сколько угодно бомбиться об этот код, но олимпиадничек его написал достаточно оптимально и забыл, потому что он больше нахуй не кому не нужен, потому что в нем баги врядли есть.
        Ответить
        • Лол, с чего бы мне бомбиться? Наоборот, мне часто нравится видеть подобное говнецо. Мне же не нужно этот говнокод сопровождать или использовать.

          Насчет "достаточно оптимально" - вранье. Этот код ОЧЕНЬ НЕОПТИМАЛЬНЫЙ. Про более оптимальные методы - читай мои же комментарии к этому говнокоду
          Ответить
          • Ну значит ты удалишь эту функцию и напишешь свою с нуля - такую же нечитаемую.
            Ответить
            • Интересно, а вот если взять какую-то выскоуровневную функцию типа memcmp
              и вместо
              pv[i] == 'h' && pv[i + 1] == 't' && pv[i + 2] == 't' && pv[i + 3] == 'p'
              сделать
              const static char http_prefix[] = {'h', 't', 't', 'p'};
              
              if (memcmp(govno, http_prefix, sizeof(http_prefix)) == 0) {
              ...

              ..то vk сразу же начнет тормозить, ляжет под нагрузкой и программиста выгонят?
              Ответить
    • К слову о парсерах: http://govnokod.ru/18277
      Ответить
    • Интересно, у ВК весь код такой?
      Ответить

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