1. Куча / Говнокод #27927

    +4

    1. 1
    2. 2
    3. 3
    4. 4
    function H2I takes handle h returns integer
      return h
      return 0
    endfunction

    Return Bug. Интересно, кто-то ещё помнит?

    Запостил: [email protected], 06 Января 2022

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

    • В JASS хэндл (указатель) был совместим с типом integer. Технически вернуть его было нельзя — компилятор ругался. Но у проверки типа возвращаемого значения была одна особенность — проверялся только последний return.

      Этим нехитрым способом преобразования хэндла в число пользовались многие годы, пока с его помощью не сумели выполнить произвольный код. После этого баг в спешном порядке починили и добавили нативные улучшения, к примеру, хэштаблицу, для эмуляции которой и использовался обычно RB.

      Помимо RB существовал также Return Nothing Bug, который открыли незадолго до фикса всей этой херни.

      Выглядел он так:
      function HandleHelper takes handle h returns handle
          return h
      endfunction
      
      function H2I tajes handle h returns integer
          call HandleHelper(h)
          if false then
              return 0
          endif
      endfunction
      Если по какой-то причине функция не вернула значение, то использовалось последнее значение, которое вернула какая-либо функция. Недосягаемый return нужен, чтобы компилятор не ругался.

      Баги с возвратом — не единственные в JASS. К примеру, локальные переменные, содержащие хэндлы, время жизни которых завершилось, всё ещё считались содержащими хэндл и не давали сборщику мусора его собрать. Поэтому можно было увидеть что-то типа
      function foo takes nothing returns nothing
          local widget w
          w = getWidget()
          . . .
          DestroyWidget(w) //Уничтожаем объект
          set w = null // Очищаем хэндл
      endfuntion


      Ещё одной интересной возможностью была возможность обращаться и записывать произвольные файлы. Оригинально фича была создана для предзагрузки необходимых файлов для уменьшения лага на старте, поэтому основной директорией была директория игры. Но используя ".." можно было выйти за её пределы. Потом это пофиксили засунув в сэндбокс, уникальный для карты, и сделав баг, разрешающий запись, фичей.
      Ответить
      • > Если по какой-то причине функция не вернула значение, то использовалось последнее значение, которое вернула какая-либо функция.

        Кокококое TCO!
        Ответить
      • Ну про хендлы и сборщик и сейчас во всяких c# да джавах проблема осталась... Поэтому можно увидеть что-то в духе IDisposable или как там его.
        Ответить
      • > директория игры

        Т.е. dll'ок можно было подсыпать?
        Ответить
        • К сожалению, ты ограничен тестовым режимом и ASCII. Но, можно вшить полезную нагрузку в карту, которая по сути архив, создать батник в автозагрузке, который распаковывает карту, вытаскивает, что нужно, и распихивает по местам.
          Ответить
          • > ты ограничен тестовым режимом и ASCII
            Как будто на этом сайте это кого-то останавливало.
            Ответить
          • > ограничен

            Физически или всё-таки можно через какой-то баг слепить строку с не-аски? А текстовый режим -- не такая уж и проблема, если с 0x0A аккуратно работать (или не юзать).
            Ответить
      • >Но используя ".." можно было выйти за её пределы.
        какая детская ошибка )))
        Ответить
        • > детская

          Это классика, это знать надо...

          Да и в каталог с самой игрой тоже как-то не айс срать. У факторио для этого есть отдельные каталоги screenshot и script-output, к примеру.
          Ответить

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