Школоло / Говнокод #21260 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
fstream:=tstreamex.Create(signaturepath,fmShareDenyWrite);
    FLock.Enter;
    try
      while not fstream.EOS do
      begin
        obj:=tsignature.create;
        try
          obj.AddingDate:=fstream.ReadDate;
          obj.Comment:=fstream.ReadString;
          fstream.ReadBuffer(Len, SizeOf(Len));
          obj.MStream.SetSize(len);
          fstream.ReadBuffer(obj.mstream.memory^, len);
          fsignlist.Add(obj);
        except
          obj.Free;
          raise esignatureloadingerror.Create('Signature read error');
        end;

Стрим читает из файла сохраненный объект. К сожалению, подобный подход используется даже в серьезных коммерческих проеках, это классика.
Если что-то поменять в файле хоть на 1 байт, стрим промахнётся мимо поля - прога либо съест всю доступную системную память либо обрушится с Access Violation.
В любом случае, память будет испорчена, и дальнейшее выполнение программы чревато UB.

Кстати, а не грозит ли юзание структур порчей памяти? Допустим, хотим определить валидность заголовка, загружаем структуру, а в файле - трешак.
Не будет ли обращения по ложному адресу? UB?

Запостил: voodoodal16 voodoodal16, (Updated )

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

    • Сюка ты меня заебал.
      Увижу при встрече, сыпану в глаза тебе горчичный порошок. Пока ты корчишься от боли, я привяжу тебя чтоб не дергался. Досыплю порошка в глаза и перемешаю в глазницах. Возьму связку сосисок и выебу тебя, как анальными бусами. Дальше взглотнешь 2 литра колы и насильно засуну в тебя ментос, чтоб твое ебало посинело. Пока ты синеешь и кричишь (От удовольствия или боли?), вспорю пузо и толстую кишку и вытощу ту связку сосисок с говном, намажу тем самой глазной горчицей и засуну в тебя. Возможно тебя вырвет, но советую этого не делать.
      Ответить
      • Слушай сюда, петушок. Какая нафиг разница? Шо то анскилл, шо то анскилл. Петушок, больше не желаю слышать в этом курятнике про эту анскиллятину!
        Ответить
        • Да шо Вы гъоворите 🙂 А по мне анскиллятина - это реплики гостей.
          Ответить
          • да нет, дружок

            писать на дельфях в 2016м это самая что ни на есть анскилябрщина
            Ответить
            • > писать на дельфях в 2016м это самая что ни на есть анскилябрщина
              Настоящая анскилябрщина - считать что год написания имеет какое-то отношение к анскилябрщине.
              Ответить
              • Ну как сказать... Для своего времени делфа вполне годная была. Назови мне ещё один иструмент со времён делфи, где можно было формошлёпствовать и ставить компоненты без ёбли.
                Ответить
                • А ещё там отладчик высокого качества. От делфи, когда садишься за нее работать, веет теплотой и дружелюбием, чего не скажешь о приблудах от майкрософта. ненавижу.
                  Ответить
  • Лолблядь, не сериализируй объекты, если сериализатор такое говно. Юзай json, например.
    Ответить
  • Ахуительно крутые спецы собрались на моём топике... Пиздец.
    Вы словно голуби: только "курлы-мурлы", а пользы - 0. Только белье на веревке пачкаете.
    Ответить
  • Я нихуя не понял, но в нормальных языках копировать содержимое файла/сокета в плоскую структуру (без указателей) - это безопасно, хоть и непортируемый говнокод.
    Ответить
  • > Кстати, а не грозит ли юзание структур порчей памяти? Допустим, хотим определить валидность заголовка, загружаем структуру, а в файле - трешак.
    Не будет ли обращения по ложному адресу? UB?

    Э, да ты совсем нуб что ли. Если размер файла меньше размера структуры то прочитать не удастся, будет исключение. А если больше - все поля прочитаются. Ну да, в полях может быть мусор, на то он и заголовок что надо будет сигнатуры сравнить, но откуда там ложные адреса и UB?
    Ответить
    • >> Если размер файла меньше размера структуры то прочитать не удастся, будет исключение. А если больше - все поля прочитаются. Ну да, в полях может быть мусор

      Если вылетело исключение - разве сие не знак того, что испорчена память? Вдруг код затёр служебные заголовки? Мусор в полях - тоже UB, как мне кажется.
      Ответить
      • > Мусор в полях - тоже UB, как мне кажется.
        Ну тогда при объявлении любой локальной переменной происходит UB. Это уже потом мы присваиваем ей значение, а до этой строчки с присвоением - полнейшее UB.
        Ответить
        • > а до этой строчки с присвоением - полнейшее UB
          Поэтому и советуют инициализировать переменную сразу в объявлении.
          Ответить
          • имеет-ли право компилятор иметь в такой переменной адрес доступного на запись firmware? или MMIO какого-то оборудовання?

            Ну типа
            char *foo;
            *(foo) = 1; //превратились в кирпич или сожгли оборудование
            Ответить
            • Вай нот? Там же любой мусор, который был на стеке/в регистре может валяться.

              Ну MMIO тебе ось в адресное пространство не замапает просто так. А вот если без оси...
              Ответить
              • >>тебе ось в адресное пространство не замапает просто так.
                Кстати!! Расскажи мне как работает MMIO и DMA при наличии MMU?
                Драйвер как-то умно читает таблицы странц и вычисляет настоящий адрес?
                Ответить
                • > Драйвер как-то умно читает таблицы странц
                  Да там у ядер специальные апишки для трансляции адресов есть, чтобы драйверы не заморачивались. Типа "выдели мне непрерывный кусок физической памяти чтобы до него могла дотянуться вот эта железка и дай адрес, который можно ей скормить" или "замапай мне mmio адреса вот этой железки". И дальше там ядро настраивает все кеши, смещения на мостах, IOMMU если есть и т.п.
                  Ответить
                  • Это про DMA, как я понял?
                    Типа драйвер просит у ядра буфер, и скармиливает его адрес DMAшке на борту карты, и карта туда пишет-пишет и потом делает interrupt?

                    а MMIO как?

                    Ну вот сидит карта на шине и слушает адреса с FOO по BAR.
                    Если я сделаю mov [FOO], 42 то FOO через MMU преврарится в черте-чо. Как же драйвер умеет записать ИМЕННО в FOO?
                    Ответить
                    • >>"замапай мне mmio адреса вот этой железки"
                      вот я в глаза долблюсь

                      теперь понятно
                      типа я говорю едру "пиши по адресу 0x1234", а оно само через таблицы высчитывает реальный адрес

                      да?
                      Ответить
                      • Ты говоришь ядру "замапай куда-нибудь mmio range вот этой вот железки". Оно тебе даёт виртуальный адрес (назовём его mapped). А таблицу трансляции для MMU для этого адреса оно тебе так настроит, что когда ты полезешь по адресу mapped + 8, то адрес уйдёт на шину правильно и, с учётом всех мостов в сторону железки, которые могут его немного подвинуть, прилетит к ней как 8 (или как base + 8, не знаю точно, где последняя трансляция идёт - в самой железке или в ближайшем к ней мосту)...
                        Ответить
                            • понятно.

                              иными словами процессор ВСЕГДА обращение к памяти прогоняет через MMU, но ядро настраивает таблицы так, что MMU мапит такие обращения не абы-куда а в нужное место.

                              ужасная жесть этот ваш протектед мод
                              то-ли дело дос:
                              char* VGA;
                              VGA = АДРЕС_КУДА_МАПИЦА_ПАМЯТЬ_ВИДЯХИ;
                              VGA[1] = YELLOW;
                              Ответить
                              • > процессор ВСЕГДА обращение к памяти прогоняет через MMU <...>
                                Так точно.

                                > ужасная жесть этот ваш протектед мод
                                Запили свою 64-битную ось с маппингом 1:1 🙂
                                Ответить
                                • не смогу. Бог с ним с MMIO, обычную память-то операционка все равно должна раскидывать.
                                  Программ-то больше чем одна)
                                  Ответить
                                  • > Программ-то больше чем одна
                                    Ну сделай почти-однозадачную, как DOS.

                                    З.Ы. Первые iOS'ы вроде тоже как китайские телефоны были - в фоне только плейер да будильник. И ничё, пипл хавал...
                                    Ответить
                                    • "почти" -- это ты о TSRах на прерываниях?

                                      Вполне себе многозадачненько! Причем если запрограммировать таймеры (там же их было два вроде) то чем не многозадачность?;)
                                      Причем не было гонок, не нужно было делать fence потому что DOS не умел более одного CPU (да?).

                                      у iOS это связано с желанием не тратить батарейку на всяких пидарасов. Технически Darwin @ XNU вполне себе многозадачна, как ты понимаешь:)

                                      Кстати говоря даже сейчас чтобы что-то делать в офне нужно это явно попросить (через plist) и список дел крайне ограничен) Тебя либо "иногда будут будить", либо разрешат быть всегда в фоне если ты плеер или навигатор.

                                      Ну то-есть нельзя невозбранно простые числа искать за счет пользователя в фоне. А в ондроиде можно)
                                      Ответить
                                      • > А в ондроиде можно
                                        Если есть право на wake lock. Иначе телефон всё-таки забьёт и уснёт.
                                        Ответить
                                          • > сервис-то можно сделать
                                            Один хуй засыпает... Без wake lock у меня не получалось нормально дёргать странички с ГК. Сервис просыпался только с какими-нибудь гугловскими прогами или когда экран включал... Алармы тоже не особо помогают без лока, чуть управление вернёшь - сразу в сон.
                                            Ответить
    • Ну чексуммы только от случайных повреждений спасают (и то с какой-то вероятностью). А вдруг кто-то специально сформировал кривой файл?
      Ответить
      • З.Ы. Ну или у отправителя какой-то сбой случился, но чексуммы на мусор он насчитал корректно.
        Ответить
        • Ну если структура состоит только из примитивов и в ней нет указателей - ничего страшного не случится. Ситуация ровно такая же, как если тебе в консольке или gui передадут мусор вместо данных.
          Ответить
        • Совсем ламер чтоли? А в жейсоне твоем мусор нельзя написать чтоли в значениях? Что так входные данные надо проверять, что эдак.
          Ответить
          • Ты скорее всего промахнулся комментом, ибо на джейсоне я не пишу.
            Ну и как их проверить? Ведь в любом случае будет утечка памяти.
            Ответить
      • > кто-то специально сформировал кривой файл?

        Написание "нормального" сериализатора/десиализатора — задача сама по себе нетривиальная, особенно, если нужно энкодить указатели.

        Какую именно проблему решаем-то?

        Если хочется не читать гигабайты при случайных повреждениях — добавляем чексуммы + проверяем, что размеры буферов адекватные.

        Когда я пилил специализированную штуку для хранения на диске, я вообще ничего в память не копировал: хранил файлы так, чтобы их можно было mmap-ить в память + использовал чексуммы для проверки записей.
        Правда, была завязка на 64-разрядные системы — файлы были большие.
        Ответить
        • Лол, как будто ядро не загружает в паиять ммапнутый файл при первом обращении
          Ответить
          • А что, загружает? Я думал, файлы попадают в память постранично.
            Ответить
              • Ну ты сорвал покровы. Когда читаешь файл read'ом, страницы все равно сначала копируются в кэш, а потом еще раз копируются в пользовательский буфер. Так что при мапинге файла меньше копирований и потенциально меньше переходов в ядро. Так-то, в яндексе веников не вяжут, это пирфоманс.
                Ответить
                • > в яндексе веников не вяжут, это пирфоманс

                  Это ещё до яндекса было, но в яндексе тоже любят mmap.
                  Не столько из-за выигрыша пирфоманса на копировании (который не такой уж и большой, кстати), сколько из возможности быстро начать обрабатывать запросы, не дожидаясь, пока распарсится в память здоровенный индекс.
                  Ответить
                • Да я не против ммапа, сам пользуюсь. Тупо меньше писать, чем читать вручную
                  Ответить
                • > страницы все равно сначала копируются в кэш, а потом еще раз копируются в пользовательский буфер.
                  Я даже больше тебе скажу. При передачи из ядра в память приложения - они копируются ещё раз. С винта читается в буфер через DMA, а он может работать только с данными выравненными на границу параграфа. Да и не гоже читать в чужую память, ибо глядишь пока драйвер "дмашкой" будет выжидать раскручивания цилиндров винта и затем хреначить в буфер юзера - процесс за это время успеет повалится. Так что сначала хуярят в страницу в кернелспейсе, а потом в страницу юзерспейса уже перекопирывают. А там ещё всякие промежуточные менеджеры есть в оси в стеке драйверов, которым нужно поснифать твои буфера для каспера например или что-то ещё сделать, так что и там все копируется в очередной раз. Так что не так страшно будет пару копирований или десятка. С винта все равно на много порядков медленне поднимается. Ну а так да, если мапиш память - там групка страниц сразу переписывается с винта, а потом без копирований эта групка страниц просто ремапится изкернелспейса драйвера в юзерспейс. В целом ммапингчтение обычно медленне обычного чтения, так как префетча обычно нет или он работает адекватно только под некоторые применения в приложениях.
                  Ответить
                  • > При передачи из ядра в память приложения - они копируются ещё раз.
                    Шта? Я и сказал, что сначала кусок файла вычитывается в страницу пейджкеша, а потом копируется в юзерспейс. Где там "еще раз"?
                    Ответить
                    • Кешер винта отдельно (часть ос), драйвер винта с в кернелспейсе - отдельно, приложение в юзерспейсе - отдельно. Приложению страницы из кешера отдавать не станут напрямую, как и кешеру из драйвера винта тоже не станут. Так что везде копирование. Их там больше чем ты думаешь. Кешер обычно частично в кернеле, частично в юзерспейсе работает, но это от версии оси и её назначения сильно зависит.

                      А так нагрузка на системный своп сильно снижается с юзаньем мапинга, тк по сути замапленный файл становится свопфайлом и можно любую давно не юзанную страницу выгрузить, а вот если ты себе закопировал обычным ридом в буфер приложухи в хип - тут этот буфер только в основной системный своп отправлять, которого может и не хватить
                      Ответить
                      • Я не втыкаю, что ты говоришь тут. Кусок файла вычитывается в пейджкэш. Дальше если read, то из пейджкэша копируется в пользовательский буфер, если mmap, то страница мапится в память процесса без копирований. С чем ты споришь-то, ты можешь пояснить конкретно?
                        Ответить

                        • > Я не втыкаю
                          А я зато втыкнул защеку, проверь

                          > Я не втыкаю
                          Да не страшно.
                          Ответить
                            • Хорошо, уже начал, проверь

                              Я это к тому, что копирований больше чем ты думаешь и это на перформанс не особо то влияет из-за латентности винта
                              Ответить
                              • Во-первых, ты не знаешь, что я думаю, во-вторых, ты кроме тех, что назвал я, ты назвал только копирование из драйвера в пейджкэш. В-третьих, если приложение не только файоы с диска читает, но майнит биточки, то такты цпу лишними не будут. Че ты тут умничаешь? Не знаешь, не лезь.
                                Ответить
                                • > Во-первых, ты не знаешь, что я думаю
                                  Ты же сам сказал что ты думаешь. Или ты говоришь не то, что думаешь? Или ты говоришь не думая?
                                  Ответить
                                    • Да и не ебу я сколько их там. И ты тоже ничего конкретного не сказал, пиздун.
                                      Ответить
                                • > В-третьих, если приложение не только файоы с диска читает, но майнит биточки, то такты цпу лишними не будут
                                  У обычного рида тоже плюсы свои есть. У него больше троугхпут и лучше работа кешера с точки зрения кешмисов, чем у ммапа, так что ещё бабушка на двое сказала, что лучше для конкретной ситуации. Не чего думать категорями царских оптимизаций экономий на спичках
                                  Ответить
                                  • Блядь, как у вас всё сложно. Нет, лучше писать на "PHP" с использованием "DevelNext"-а - он сам прекрасно управится с памятью, кэшем и прочей поеботой...
                                    Ответить
                • Эх, как прискорбно сознавать, что краш тестером анусов, конардой и хуестой был... 1024--


                  Покайся, покайся!..
                  Ответить
              • Еще мне кажется, роман кашiцiн говорил о том, что ему не нужно строить в памяти структуру на основе данных из файла, а не о том, что не надо данные загружать.
                Ответить
        • Виват, Кашицын.
          >>Если хочется не читать гигабайты при случайных повреждениях — добавляем чексуммы + проверяем, что размеры буферов адекватные.
          У меня так сделано, но почему-то это показалось мне хаком. Оказывается, не ламерство.


          BagorCtretora,
          huesto,
          guestinho,
          CrashTesterAnusov,
          bagor,
          barop
          - попадают в список свитка-минусатора. Вы для меня больше не существуете. Прощайте.
          Ответить
          • Хуле ты нас с хуесто в спамеры записал?
            Очень сильно рискуешь, за нами большая армия ботов.
            Ответить
          • Почему эти чудаки ведут себя как один человек, но друг с другом постоянно собачатся?
            Ответить
              • Ты когда осилишь автоматизировать свой безблагодатный труд? Неужели не раздражает делать одно и тоже однообразное действие? Тогда какой-же ты программист, если не можешь автоматизировать простые действия?
                Ответить
                  • Я её как минимум разноображу интересными языками и алгоритмами. А вот когда ты осилишь хоть что-то из автоматизации? Я из тех, кто ненавидит повторяющиеся действия, которые мне надо делать самостоятельно. Поэтому я их или автоматизирую, или не делаю совсем.
                    Ответить
                    • > Я из тех, кто ненавидит повторяющиеся действия, которые мне надо делать самостоятельно.
                      Надеюсь, в виме сидишь, не правишь в ide повторяющиеся строки руками?
                      Ответить
                      • В гитхаб атоме есть мощные средства для редактирования копипаста: поиск и замена по всему проекту регулярками, множественные курсоры позволяющие редактировать сразу несколько одинаковых участков кода.
                        Ответить
                        • Это у всех есть. Но все равно 100% повторяющихся действий они не автоматизируют.
                          Ответить
                        • >>В гитхаб атоме есть мощные
                          ахахахаха

                          и в нотпаде тоже, ага
                          Ответить
                        • >> множественные курсоры позволяющие редактировать сразу несколько одинаковых участков кода.

                          чтобы копипаст не стал проблемой
                          Ответить
                        • У этого гостя аватарка другая на хузе. Какой анскилл )))
                          Ответить

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

Помни, guest, за тобой могут следить!

    А не использовать ли нам bbcode?


    8