Как сохранить форматирование чисел в многозначном поле со списком?

Возражение полностью законно.

Предположим, что ваша команда выглядит так:

def post_result(result_string):
  os.system('curl http://example.com/report-result/%s' % (result_string,))

Теперь, что произойдет, если вам сообщают о результатах, которые содержат ; rm -rf ~? Оболочка, вызванная os.system(), запускает curl http://example.com/report-result/, а затем выполняет вторую команду rm -rf ~.

Несколько наивных попыток исправления не работают.

например:

# Adding double quotes should work, right?
# WRONG: ''; rm -rf ~'' doesn't work here, but $(rm -rf ~) still does.
os.system('curl http://example.com/report-result/"%s"' % (result_string,))

# ...so, how about single quotes?
# STILL WRONG: $(rm -rf ~) doesn't work on its own, but result_string="'$(rm -rf ~)'" does.
os.system("curl http://example.com/report-result/'%s'" % (result_string,))

Даже если вы избегаете прямых уязвимостей инъекции оболочки, использование оболочки предоставляет вам другие типы ошибок.

Во время запуска оболочка выполняет ряд операций на основе содержимого файловой системы и переменных среды. Если ненадежный пользователь может манипулировать вашей программой в настройке переменных окружения по своему выбору до вызова os.system(), они могут заставить файл с именем в ENV выполнить свои команды; может теневые команды с экспортированными функциями или может вызвать другие озорства. См. ShellShock для хорошо опубликованного исторического примера.

И прежде чем рассматривать другие вещи, которые могут случиться с вашими данными. Если вы передаете имя файла в оболочку, но неизвестно вам, оно содержит символы пробелов и glob, это имя файла может быть разделено на / заменено другими именами.


Официальная документация Python предупреждает против shell.

Цитирование предупреждения из документации модуля Python subprocess , что также актуально здесь:

Предупреждение: выполнение команд оболочки которые включают неанитированный ввод из ненадежного источника, делают программу уязвимой для инъекции оболочки, серьезную проблему безопасности, которая может привести к произвольному выполнению команды. По этой причине использование shell=True сильно не рекомендуется в случаях, когда командная строка построена из внешнего ввода:

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

shell=False отключает все функции на основе оболочки, но не страдает от этого уязвимость; см. примечание в документации конструктора Popen для полезных подсказок при работе shell=False.

При использовании shell=True, pipes.quote() можно использовать для правильного удаления пробелов и метасимволов оболочки в строках, которые будут использоваться для создания команд оболочки.

os.system() имеет все те же ошибки, что и subprocess.Popen(..., shell=True) - даже больше сбоев, поскольку subprocess.Popen() обеспечивает способ передачи данных вне диапазона из кода, и поэтому можно безопасно использовать .


Исходные библиотеки Python не вызывают оболочки для работы, которые Python может работать.

Python имеет библиотеку socket в своем стандартном библиотечном интерфейсе, который непосредственно вызывает вызовы операционной системы и libc для создания сетевых подключений и взаимодействия с ними. В этих системных вызовах нет оболочки; аргументами являются C-структуры, строки C и т. д .; поэтому они не подвержены уязвимостям инъекции оболочки так же, как os.system().

Некоторые библиотеки Python, такие как libcurl, могут быть немного менее родными, поскольку они используют свои собственные библиотеки C, а чем вызов только операционной системе через функции, входящие в состав самой Python; даже тогда эти системные системы на уровне OS находятся на гораздо более низком уровне, чем любая оболочка.

0
задан a_horse_with_no_name 19 January 2019 в 12:04
поделиться

1 ответ

Полагаю, вы имеете в виду ListBox, а не Combobox, верно?

Так что я также предполагаю, что у вас уже есть код для чтения выбранных элементов вашего ListBox, например:

Dim item As Variant
For Each item In YourListBox.ItemsSelected
    Debug.Print YourListBox.ItemData(item)
Next

По поводу вашей проблемы:

Вы писали, что поле таблиц Reference_ID хранит само число, но, поскольку оно отформатировано как "R-"000, оно отображает значения, подобные R-003.

Итак, вы уже знаете, что само сохраненное значение не форматируется. Вы можете проверить это, извлекая данные следующим образом:

?DLookup("Reference_ID","References","Reference_ID = 3")

Это будет отображаться 3, а не R-003.

То же самое относится и к чтению данных из выбранных элементов ListBoxes.

Насколько я знаю, вы не можете прочитать форматированный текст из ListBox. Но вы можете самостоятельно отформатировать значение чтения:

Dim item As Variant
For Each item In YourListBox.ItemsSelected
    Debug.Print Format(YourListBox.ItemData(item), "R-000")
Next

Другой подход может заключаться в том, чтобы установить для источника строки вашего ListBox уже отформатированные значения:

Select Format(Reference_ID, "R-000") From References
0
ответ дан Unhandled Exception 19 January 2019 в 12:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: