[PATCH 5/5] Escape text inserted into markup strings
David Shea
dshea at redhat.com
Wed Oct 16 17:27:23 UTC 2013
---
pyanaconda/ui/gui/hubs/__init__.py | 6 +++---
pyanaconda/ui/gui/spokes/advstorage/iscsi.glade | 2 +-
pyanaconda/ui/gui/spokes/advstorage/iscsi.py | 12 ++++++++++--
pyanaconda/ui/gui/spokes/keyboard.py | 4 ++--
pyanaconda/ui/gui/spokes/langsupport.py | 8 ++++++--
pyanaconda/ui/gui/spokes/lib/accordion.py | 7 +++++--
pyanaconda/ui/gui/spokes/lib/cart.py | 5 ++++-
pyanaconda/ui/gui/spokes/lib/resize.py | 15 ++++++++++-----
pyanaconda/ui/gui/spokes/lib/summary.py | 7 +++++--
pyanaconda/ui/gui/spokes/network.py | 16 +++++++++-------
pyanaconda/ui/gui/spokes/software.py | 8 +++++---
pyanaconda/ui/gui/spokes/storage.py | 19 +++++++++++--------
pyanaconda/ui/gui/spokes/welcome.py | 10 +++++++---
pyanaconda/ui/gui/utils.py | 9 +++++++++
14 files changed, 87 insertions(+), 41 deletions(-)
diff --git a/pyanaconda/ui/gui/hubs/__init__.py b/pyanaconda/ui/gui/hubs/__init__.py
index f142a18..f889e92 100644
--- a/pyanaconda/ui/gui/hubs/__init__.py
+++ b/pyanaconda/ui/gui/hubs/__init__.py
@@ -31,7 +31,7 @@ from pyanaconda.ui import common
from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.gui.categories import collect_categories
from pyanaconda.ui.gui.spokes import StandaloneSpoke, collect_spokes
-from pyanaconda.ui.gui.utils import gtk_call_once
+from pyanaconda.ui.gui.utils import gtk_call_once, escape_markup
from pyanaconda.constants import ANACONDA_ENVIRON
import logging
@@ -225,7 +225,7 @@ class Hub(GUIObject, common.Hub):
if not selectors:
continue
- label = Gtk.Label("<span font-desc=\"Sans 14\">%s</span>" % _(obj.title))
+ label = Gtk.Label("<span font-desc=\"Sans 14\">%s</span>" % escape_markup(_(obj.title)))
label.set_use_markup(True)
label.set_halign(Gtk.Align.START)
label.set_margin_top(12)
@@ -257,7 +257,7 @@ class Hub(GUIObject, common.Hub):
def _updateCompleteness(self, spoke):
spoke.selector.set_sensitive(spoke.ready)
spoke.selector.set_property("status", spoke.status)
- spoke.selector.set_tooltip_markup(GLib.markup_escape_text(spoke.status))
+ spoke.selector.set_tooltip_markup(escape_markup(spoke.status))
spoke.selector.set_incomplete(not spoke.completed and spoke.mandatory)
self._handleCompleteness(spoke)
diff --git a/pyanaconda/ui/gui/spokes/advstorage/iscsi.glade b/pyanaconda/ui/gui/spokes/advstorage/iscsi.glade
index 8050e06..2e3ad63 100644
--- a/pyanaconda/ui/gui/spokes/advstorage/iscsi.glade
+++ b/pyanaconda/ui/gui/spokes/advstorage/iscsi.glade
@@ -682,7 +682,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">The following nodes were discovered using the iSCSI initiator <b>%(initiatorName)s</b> using the target IP address <b>%(targetAddress)s</b>. Please select which nodes you wish to log into:</property>
+ <property name="label">The following nodes were discovered using the iSCSI initiator <b>%(initiatorName)s</b> using the target IP address <b>%(targetAddress)s</b>. Please select which nodes you wish to log into:</property>
<property name="use_markup">True</property>
<property name="wrap">True</property>
</object>
diff --git a/pyanaconda/ui/gui/spokes/advstorage/iscsi.py b/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
index b2abccc..223e1cd 100644
--- a/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
+++ b/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
@@ -26,6 +26,8 @@ from gi.repository import GLib
from pyanaconda import constants
from pyanaconda.threads import threadMgr, AnacondaThread
from pyanaconda.ui.gui import GUIObject
+from pyanaconda.ui.gui.utils import escape_markup
+from pyanaconda.i18n import _
from pyanaconda import nm
__all__ = ["ISCSIDialog"]
@@ -264,9 +266,15 @@ class ISCSIDialog(GUIObject):
# Now get the node discovery credentials.
credentials = discoverMap[self._authNotebook.get_current_page()](self.builder)
+ discoveredLabelText = _("The following nodes were discovered using the iSCSI initiator "\
+ "<b>%(initiatorName)s</b> using the target IP address "\
+ "<b>%(targetAddress)s</b>. Please select which nodes you "\
+ "wish to log into:") % \
+ {"initiatorName": escape_markup(credentials.initiator),
+ "targetAddress": escape_markup(credentials.targetIP)}
+
discoveredLabel = self.builder.get_object("discoveredLabel")
- discoveredLabel.set_markup(discoveredLabel.get_label() % {"initiatorName": credentials.initiator,
- "targetAddress": credentials.targetIP})
+ discoveredLabel.set_markup(discoveredLabelText)
bind = self._bindCheckbox.get_active()
diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py
index f7c8c99..b5d3af0 100644
--- a/pyanaconda/ui/gui/spokes/keyboard.py
+++ b/pyanaconda/ui/gui/spokes/keyboard.py
@@ -25,7 +25,7 @@ from gi.repository import Gkbd, Gdk, Gtk
from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.gui.spokes import NormalSpoke
from pyanaconda.ui.gui.categories.localization import LocalizationCategory
-from pyanaconda.ui.gui.utils import enlightbox, gtk_call_once
+from pyanaconda.ui.gui.utils import enlightbox, gtk_call_once, escape_markup
from pyanaconda import keyboard
from pyanaconda import flags
from pyanaconda.i18n import _, N_
@@ -46,7 +46,7 @@ def _show_layout(column, renderer, model, itr, wrapper):
def _show_description(column, renderer, model, itr, wrapper):
value = wrapper.get_switch_opt_description(model[itr][0])
if model[itr][1]:
- value = "<b>%s</b>" % value
+ value = "<b>%s</b>" % escape_markup(value)
renderer.set_property("markup", value)
class AddLayoutDialog(GUIObject):
diff --git a/pyanaconda/ui/gui/spokes/langsupport.py b/pyanaconda/ui/gui/spokes/langsupport.py
index 776791e..9c37895 100644
--- a/pyanaconda/ui/gui/spokes/langsupport.py
+++ b/pyanaconda/ui/gui/spokes/langsupport.py
@@ -24,6 +24,7 @@ from gi.repository import Pango
from pyanaconda.flags import flags
from pyanaconda.i18n import N_
from pyanaconda.ui.gui.spokes import NormalSpoke
+from pyanaconda.ui.gui.utils import escape_markup
from pyanaconda.ui.gui.categories.localization import LocalizationCategory
from pyanaconda.ui.gui.spokes.lib.lang_locale_handler import LangLocaleHandler
from pyanaconda import localization
@@ -108,11 +109,14 @@ class LangsupportSpoke(LangLocaleHandler, NormalSpoke):
return True
def _add_language(self, store, native, english, lang):
- native_span = '<span lang="%s">%s</span>' % (lang, native)
+ native_span = '<span lang="%s">%s</span>' % \
+ (escape_markup(lang), escape_markup(native))
store.append([native_span, english, lang])
def _add_locale(self, store, native, locale):
- native_span = '<span lang="%s">%s</span>' % (re.sub(r'\..*', '', locale), native)
+ native_span = '<span lang="%s">%s</span>' % \
+ (escape_markup(re.sub(r'\..*', '', locale)),
+ escape_markup(native))
# native, locale, selected, additional
store.append([native_span, locale, locale in self._selected_locales,
diff --git a/pyanaconda/ui/gui/spokes/lib/accordion.py b/pyanaconda/ui/gui/spokes/lib/accordion.py
index 5990332..b527021 100644
--- a/pyanaconda/ui/gui/spokes/lib/accordion.py
+++ b/pyanaconda/ui/gui/spokes/lib/accordion.py
@@ -24,6 +24,7 @@ from blivet.size import Size
from pyanaconda.i18n import _
from pyanaconda.product import productName, productVersion
+from pyanaconda.ui.gui.utils import escape_markup
from gi.repository.AnacondaWidgets import MountpointSelector
from gi.repository import Gtk
@@ -82,7 +83,8 @@ class Accordion(Gtk.Box):
def addPage(self, contents, cb=None):
label = Gtk.Label()
- label.set_markup("""<span size='large' weight='bold' fgcolor='black'>%s</span>""" % contents.pageTitle)
+ label.set_markup("""<span size='large' weight='bold' fgcolor='black'>%s</span>""" %
+ escape_markup(contents.pageTitle))
label.set_alignment(0, 0.5)
label.set_line_wrap(True)
@@ -167,7 +169,8 @@ class Page(Gtk.Box):
def _make_category_label(self, name):
label = Gtk.Label()
- label.set_markup("""<span fgcolor='dark grey' size='large' weight='bold'>%s</span>""" % name)
+ label.set_markup("""<span fgcolor='dark grey' size='large' weight='bold'>%s</span>""" %
+ escape_markup(name))
label.set_halign(Gtk.Align.START)
label.set_margin_left(24)
return label
diff --git a/pyanaconda/ui/gui/spokes/lib/cart.py b/pyanaconda/ui/gui/spokes/lib/cart.py
index b3a2ca5..db34a6d 100644
--- a/pyanaconda/ui/gui/spokes/lib/cart.py
+++ b/pyanaconda/ui/gui/spokes/lib/cart.py
@@ -25,6 +25,7 @@ from gi.repository import Gtk
from pyanaconda.i18n import _, P_
from pyanaconda.ui.lib.disks import size_str
from pyanaconda.ui.gui import GUIObject
+from pyanaconda.ui.gui.utils import escape_markup
from blivet.size import Size
__all__ = ["SelectedDisksDialog"]
@@ -134,7 +135,9 @@ class SelectedDisksDialog(GUIObject):
"(unpartitioned and in filesystems)",
"<b>%(count)d disks; %(size)s capacity; %(free)s free space</b> "
"(unpartitioned and in filesystems)",
- count) % {"count" : count, "size" : size, "free" : free}
+ count) % {"count" : count,
+ "size" : escape_markup(size),
+ "free" : escape_markup(free)}
self._summary_label.set_markup(text)
# signal handlers
diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py
index 36ae4b1..755faea 100644
--- a/pyanaconda/ui/gui/spokes/lib/resize.py
+++ b/pyanaconda/ui/gui/spokes/lib/resize.py
@@ -27,6 +27,7 @@ from gi.repository import Gdk, Gtk
from pyanaconda.i18n import _, N_, P_
from pyanaconda.ui.lib.disks import size_str
from pyanaconda.ui.gui import GUIObject
+from pyanaconda.ui.gui.utils import escape_markup
from blivet.size import Size
__all__ = ["ResizeDialog"]
@@ -74,7 +75,7 @@ class ResizeDialog(GUIObject):
self._required_label = self.builder.get_object("requiredSpaceLabel")
markup = self._required_label.get_label()
- self._required_label.set_markup(markup % size_str(self.payload.spaceRequired))
+ self._required_label.set_markup(markup % escape_markup(size_str(self.payload.spaceRequired)))
self._reclaimDescLabel = self.builder.get_object("reclaimDescLabel")
@@ -156,7 +157,8 @@ class ResizeDialog(GUIObject):
canShrinkSomething = True
else:
freeSize = dev.size
- resizeString = "<span foreground='grey'>%s</span>" % _("Not resizeable")
+ resizeString = "<span foreground='grey'>%s</span>" % \
+ escape_markup(_("Not resizeable"))
self._diskStore.append(itr, [dev.id,
self._description(dev),
@@ -174,7 +176,8 @@ class ResizeDialog(GUIObject):
diskFree = free_space[disk.name][0]
converted = diskFree.convertTo(spec="mb")
if int(converted):
- freeSpaceString = "<span foreground='grey' style='italic'>%s</span>" % _("Free space")
+ freeSpaceString = "<span foreground='grey' style='italic'>%s</span>" % \
+ escape_markup(_("Free space"))
self._diskStore.append(itr, [disk.id,
freeSpaceString,
"",
@@ -212,11 +215,13 @@ class ResizeDialog(GUIObject):
if nDisks is not None and totalReclaimable is not None:
text = P_("<b>%(count)s disk; %(size)s reclaimable space</b> (in filesystems)",
"<b>%(count)s disks; %(size)s reclaimable space</b> (in filesystems)",
- nDisks) % {"count" : nDisks, "size" : size_str(totalReclaimable)}
+ nDisks) % {"count" : escape_markup(str(nDisks)),
+ "size" : escape_markup(size_str(totalReclaimable))}
self._reclaimable_label.set_markup(text)
if selectedReclaimable is not None:
- text = _("Total selected space to reclaim: <b>%s</b>") % size_str(selectedReclaimable)
+ text = _("Total selected space to reclaim: <b>%s</b>") % \
+ escape_markup(size_str(selectedReclaimable))
self._selected_label.set_markup(text)
def _setup_slider(self, device, value):
diff --git a/pyanaconda/ui/gui/spokes/lib/summary.py b/pyanaconda/ui/gui/spokes/lib/summary.py
index 8d320cc..2b3eb86 100644
--- a/pyanaconda/ui/gui/spokes/lib/summary.py
+++ b/pyanaconda/ui/gui/spokes/lib/summary.py
@@ -20,6 +20,7 @@
#
from pyanaconda.ui.gui import GUIObject
+from pyanaconda.ui.gui.utils import escape_markup
from blivet.deviceaction import ACTION_TYPE_DESTROY, ACTION_TYPE_RESIZE, ACTION_OBJECT_FORMAT
@@ -40,9 +41,11 @@ class ActionSummaryDialog(GUIObject):
mountpoint = ""
if action.type in [ACTION_TYPE_DESTROY, ACTION_TYPE_RESIZE]:
- typeString = """<span foreground='red'>%s</span>""" % action.typeDesc.title()
+ typeString = """<span foreground='red'>%s</span>""" % \
+ escape_markup(action.typeDesc.title())
else:
- typeString = """<span foreground='green'>%s</span>""" % action.typeDesc.title()
+ typeString = """<span foreground='green'>%s</span>""" % \
+ escape_markup(action.typeDesc.title())
if action.obj == ACTION_OBJECT_FORMAT:
mountpoint = getattr(action.device.format, "mountpoint", "")
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py
index d4d1803..559e999 100644
--- a/pyanaconda/ui/gui/spokes/network.py
+++ b/pyanaconda/ui/gui/spokes/network.py
@@ -39,7 +39,7 @@ from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.gui.spokes import NormalSpoke, StandaloneSpoke
from pyanaconda.ui.gui.categories.system import SystemCategory
from pyanaconda.ui.gui.hubs.summary import SummaryHub
-from pyanaconda.ui.gui.utils import gtk_call_once, enlightbox
+from pyanaconda.ui.gui.utils import gtk_call_once, enlightbox, escape_markup
from pyanaconda.ui.common import FirstbootSpokeMixIn
from pyanaconda import network
@@ -626,12 +626,14 @@ class NetworkControlBox(object):
and device.get_device_type() == NetworkManager.DeviceType.ETHERNET
and not device.get_carrier()):
# Translators: ethernet cable is unplugged
- unplugged = ', <i>%s</i>' % _("unplugged")
- title = '<span size="large">%s (%s%s)</span>' % (self._dev_type_str(device),
- device.get_iface(),
- unplugged)
- title += '\n<span size="small">%s %s</span>' % (device.get_vendor() or "",
- device.get_product() or "")
+ unplugged = ', <i>%s</i>' % escape_markup(_("unplugged"))
+ title = '<span size="large">%s (%s%s)</span>' % \
+ (escape_markup(self._dev_type_str(device)),
+ escape_markup(device.get_iface()),
+ unplugged)
+ title += '\n<span size="small">%s %s</span>' % \
+ (escape_markup(device.get_vendor()) or "",
+ escape_markup(device.get_product()) or "")
return title
def _dev_type_str(self, device):
diff --git a/pyanaconda/ui/gui/spokes/software.py b/pyanaconda/ui/gui/spokes/software.py
index f4b7995..285e857 100644
--- a/pyanaconda/ui/gui/spokes/software.py
+++ b/pyanaconda/ui/gui/spokes/software.py
@@ -30,7 +30,7 @@ from pyanaconda import constants
from pyanaconda.ui.communication import hubQ
from pyanaconda.ui.gui.spokes import NormalSpoke
from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog
-from pyanaconda.ui.gui.utils import enlightbox, gtk_action_wait
+from pyanaconda.ui.gui.utils import enlightbox, gtk_action_wait, escape_markup
from pyanaconda.ui.gui.categories.software import SoftwareCategory
import sys
@@ -248,7 +248,8 @@ class SoftwareSelectionSpoke(NormalSpoke):
for environment in self.payload.environments:
(name, desc) = self.payload.environmentDescription(environment)
- itr = self._environmentStore.append([environment == self.environment, "<b>%s</b>\n%s" % (name, desc), environment])
+ itr = self._environmentStore.append([environment == self.environment, "<b>%s</b>\n%s" % \
+ (escape_markup(name), escape_markup(desc)), environment])
# Either:
# (1) Select the environment given by kickstart or selected last
# time this spoke was displayed; or
@@ -276,7 +277,8 @@ class SoftwareSelectionSpoke(NormalSpoke):
else:
selected = grp in self.selectedGroups
- self._addonStore.append([selected, "<b>%s</b>\n%s" % (name, desc), grp, False])
+ self._addonStore.append([selected, "<b>%s</b>\n%s" % \
+ (escape_markup(name), escape_markup(desc)), grp, False])
def refreshAddons(self):
self._addonStore.clear()
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 99450b9..5b83e7f 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -49,7 +49,7 @@ from pyanaconda.ui.gui.spokes.lib.passphrase import PassphraseDialog
from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog
from pyanaconda.ui.gui.spokes.lib.resize import ResizeDialog
from pyanaconda.ui.gui.categories.system import SystemCategory
-from pyanaconda.ui.gui.utils import enlightbox
+from pyanaconda.ui.gui.utils import enlightbox, escape_markup
from pyanaconda.kickstart import doKickstartStorage, getAvailableDiskSpace
from blivet import empty_device
@@ -126,7 +126,8 @@ class InstallOptions1Dialog(GUIObject):
options_text = _("<span font-desc=\"Cantarell 11\">You have <b>%(freeSpace)s</b> "
"of free space, which is enough to install %(productName)s. "
"What would you like to do?</span>") %\
- {"freeSpace": disk_free, "productName": productName}
+ {"freeSpace": escape_markup(disk_free),
+ "productName": escape_markup(productName)}
options_label.set_markup(options_text)
label = self.builder.get_object("options1_autopart_label")
@@ -171,9 +172,10 @@ class InstallOptions1Dialog(GUIObject):
"selection</a> requires <b>%(total)s</b> of available "
"space, including <b>%(software)s</b> for software and "
"<b>%(swap)s</b> for swap space.")
- % {"product": productName,
- "total": required_space + auto_swap,
- "software": required_space, "swap": auto_swap})
+ % {"product": escape_markup(productName),
+ "total": escape_markup(str(required_space + auto_swap)),
+ "software": escape_markup(str(required_space)),
+ "swap": escape_markup(str(auto_swap))})
return sw_text
# Methods to handle sensitivity of the modify button.
@@ -248,7 +250,7 @@ class InstallOptions2Dialog(InstallOptions1Dialog):
"%s</b>. You can shrink or remove existing partitions "
"via our guided reclaim space tool, or you can adjust your "
"partitions on your own in the custom partitioning "
- "interface.") % productName
+ "interface.") % escape_markup(productName)
self.builder.get_object("options2_label2").set_markup(label_text)
self._add_modify_watcher("options2_label1")
@@ -277,7 +279,8 @@ class InstallOptions3Dialog(InstallOptions1Dialog):
label_text = (_("%(sw_text)s You don't have enough space available to install "
"<b>%(product)s</b>, even if you used all of the free space "
"available on the selected disks.")
- % {"sw_text": sw_text, "product": productName})
+ % {"sw_text": escape_markup(sw_text),
+ "product": escape_markup(productName)})
label = self.builder.get_object("options3_label1")
label.set_markup(label_text)
label.set_tooltip_text(_("Please wait... software metadata still loading."))
@@ -291,7 +294,7 @@ class InstallOptions3Dialog(InstallOptions1Dialog):
"disks for additional space, "
"modify your software selection to install a smaller "
"version of <b>%(productName)s</b>, or quit the installer.") % \
- {"productName": productName}
+ {"productName": escape_markup(productName)}
self.builder.get_object("options3_label2").set_markup(label_text)
self._add_modify_watcher("options3_label1")
diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index c6f411d..a986b73 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -26,7 +26,7 @@ import langtable
from pyanaconda.ui.gui.hubs.summary import SummaryHub
from pyanaconda.ui.gui.spokes import StandaloneSpoke
-from pyanaconda.ui.gui.utils import enlightbox, setup_gtk_direction
+from pyanaconda.ui.gui.utils import enlightbox, setup_gtk_direction, escape_markup
from pyanaconda.ui.gui.spokes.lib.lang_locale_handler import LangLocaleHandler
from pyanaconda import localization
@@ -268,11 +268,15 @@ class WelcomeLanguageSpoke(LangLocaleHandler, StandaloneSpoke):
self._languageStoreFilter.refilter()
def _add_language(self, store, native, english, lang):
- native_span = '<span lang="%s">%s</span>' % (lang, native)
+ native_span = '<span lang="%s">%s</span>' % \
+ (escape_markup(lang),
+ escape_markup(native))
store.append([native_span, english, lang, False])
def _add_locale(self, store, native, locale):
- native_span = '<span lang="%s">%s</span>' % (re.sub(r'\..*', '', locale), native)
+ native_span = '<span lang="%s">%s</span>' % \
+ (escape_markup(re.sub(r'\..*', '', locale)),
+ escape_markup(native))
store.append([native_span, locale])
# Signal handlers.
diff --git a/pyanaconda/ui/gui/utils.py b/pyanaconda/ui/gui/utils.py
index f7ad413..5e5095c 100644
--- a/pyanaconda/ui/gui/utils.py
+++ b/pyanaconda/ui/gui/utils.py
@@ -223,3 +223,12 @@ def setup_gtk_direction():
"""
Gtk.Widget.set_default_direction(get_default_widget_direction())
+
+def escape_markup(value):
+ """
+ Escape strings for use within Pango markup.
+
+ This function converts the value to a string before passing markup_escape_text().
+ """
+
+ return GLib.markup_escape_text(str(value))
--
1.8.3.1
More information about the anaconda-patches
mailing list