From 82aee30657a53bf5983ed154bf8f8e83091fbcee Mon Sep 17 00:00:00 2001 From: abakkk Date: Sun, 4 Oct 2020 10:01:55 +0200 Subject: [PATCH] fix unsanitized GType names With old GS/GJS, some GType names were generated from class names without sanitizing it (e.g. Menu.ActionButton). Instead of defining all GType names, sanitize all class name as it was GType name, and let GJS generated GType name securely when it is necessary. Fix #46. --- area.js | 3 ++- elements.js | 7 ++++--- extension.js | 9 +++++---- files.js | 9 +++++---- helper.js | 3 ++- menu.js | 7 ++++--- prefs.js | 36 +++++++++++------------------------- 7 files changed, 33 insertions(+), 41 deletions(-) diff --git a/area.js b/area.js index 3b5444c..f629462 100644 --- a/area.js +++ b/area.js @@ -51,6 +51,7 @@ const TEXT_CURSOR_TIME = 600; // ms const ELEMENT_GRABBER_TIME = 80; // ms, default is about 16 ms const GRID_TILES_HORIZONTAL_NUMBER = 30; const COLOR_PICKER_EXTENSION_UUID = 'color-picker@tuberry'; +const UUID = Me.uuid.replace(/@/gi, '_at_').replace(/[^a-z0-9+_-]/gi, '_'); const { Shapes, Transformations } = Elements; const { DisplayStrings } = Menu; @@ -85,7 +86,7 @@ const getColorFromString = function(string, fallback) { // It creates and manages a DrawingElement for each "brushstroke". // It handles pointer/mouse/(touch?) events and some keyboard events. var DrawingArea = new Lang.Class({ - Name: `${Me.uuid}.DrawingArea`, + Name: `${UUID}-DrawingArea`, Extends: St.DrawingArea, Signals: { 'show-osd': { param_types: [Gio.Icon.$gtype, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_DOUBLE, GObject.TYPE_BOOLEAN] }, 'update-action-mode': {}, diff --git a/elements.js b/elements.js index b0d1868..509e219 100644 --- a/elements.js +++ b/elements.js @@ -28,6 +28,7 @@ const Pango = imports.gi.Pango; const PangoCairo = imports.gi.PangoCairo; const Me = imports.misc.extensionUtils.getCurrentExtension(); +const UUID = Me.uuid.replace(/@/gi, '_at_').replace(/[^a-z0-9+_-]/gi, '_'); var Shapes = { NONE: 0, LINE: 1, ELLIPSE: 2, RECTANGLE: 3, TEXT: 4, POLYGON: 5, POLYLINE: 6, IMAGE: 7 }; var Transformations = { TRANSLATION: 0, ROTATION: 1, SCALE_PRESERVE: 2, STRETCH: 3, REFLECTION: 4, INVERSION: 5 }; @@ -72,7 +73,7 @@ var DrawingElement = function(params) { // It can be converted into a cairo path as well as a svg element. // See DrawingArea._startDrawing() to know its params. const _DrawingElement = new Lang.Class({ - Name: `${Me.uuid}.DrawingElement`, + Name: `${UUID}-DrawingElement`, _init: function(params) { for (let key in params) @@ -626,7 +627,7 @@ const _DrawingElement = new Lang.Class({ }); const TextElement = new Lang.Class({ - Name: `${Me.uuid}.TextElement`, + Name: `${UUID}-TextElement`, Extends: _DrawingElement, toJSON: function() { @@ -766,7 +767,7 @@ const TextElement = new Lang.Class({ }); const ImageElement = new Lang.Class({ - Name: `${Me.uuid}.ImageElement`, + Name: `${UUID}-ImageElement`, Extends: _DrawingElement, toJSON: function() { diff --git a/extension.js b/extension.js index 23360d7..a6d2744 100644 --- a/extension.js +++ b/extension.js @@ -41,6 +41,7 @@ const _ = imports.gettext.domain(Me.metadata['gettext-domain']).gettext; const GS_VERSION = Config.PACKAGE_VERSION; const HIDE_TIMEOUT_LONG = 2500; // ms, default is 1500 ms +const UUID = Me.uuid.replace(/@/gi, '_at_').replace(/[^a-z0-9+_-]/gi, '_'); // custom Shell.ActionMode, assuming that they are unused const DRAWING_ACTION_MODE = Math.pow(2,14); @@ -53,7 +54,7 @@ function init() { } const Extension = new Lang.Class({ - Name: `${Me.uuid}.Extension`, + Name: `${UUID}-Extension`, _init: function() { Convenience.initTranslations(); @@ -81,7 +82,7 @@ const Extension = new Lang.Class({ // distributes keybinding callbacks to the active area // and handles stylesheet and monitor changes. const AreaManager = new Lang.Class({ - Name: `${Me.uuid}.AreaManager`, + Name: `${UUID}-AreaManager`, _init: function() { this.areas = []; @@ -560,7 +561,7 @@ const AreaManager = new Lang.Class({ // The same as the original, without forcing a ratio of 1. const OsdWindowConstraint = new Lang.Class({ - Name: `${Me.uuid}.OsdWindowConstraint`, + Name: `${UUID}-OsdWindowConstraint`, Extends: OsdWindow.OsdWindowConstraint, vfunc_update_allocation: function(actor, actorBox) { @@ -582,7 +583,7 @@ const OsdWindowConstraint = new Lang.Class({ }); const DrawingIndicator = new Lang.Class({ - Name: `${Me.uuid}.Indicator`, + Name: `${UUID}-Indicator`, _init: function() { let [menuAlignment, dontCreateMenu] = [0, true]; diff --git a/files.js b/files.js index 8334601..1f31691 100644 --- a/files.js +++ b/files.js @@ -31,6 +31,7 @@ const St = imports.gi.St; const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); +const UUID = Me.uuid.replace(/@/gi, '_at_').replace(/[^a-z0-9+_-]/gi, '_'); const EXAMPLE_IMAGE_DIRECTORY = Me.dir.get_child('data').get_child('images'); const DEFAULT_USER_IMAGE_LOCATION = GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir'], 'images']); const Clipboard = St.Clipboard.get_default(); @@ -98,7 +99,7 @@ const replaceColor = function (contents, color) { // Wrapper around image data. If not subclassed, it is used when loading in the area an image element for a drawing file (.json) // and it takes { displayName, contentType, base64, hash } as params. var Image = new Lang.Class({ - Name: `${Me.uuid}.Image`, + Name: `${UUID}-Image`, _init: function(params) { for (let key in params) @@ -193,7 +194,7 @@ var Image = new Lang.Class({ // Add a gicon generator to Image. It is used with image files and it takes { file, info } as params. const ImageWithGicon = new Lang.Class({ - Name: `${Me.uuid}.ImageWithGicon`, + Name: `${UUID}-ImageWithGicon`, Extends: Image, get displayName() { @@ -247,7 +248,7 @@ const ImageWithGicon = new Lang.Class({ // It is directly generated from a Json object, without an image file. It takes { bytes, displayName, gicon } as params. const ImageFromJson = new Lang.Class({ - Name: `${Me.uuid}.ImageFromJson`, + Name: `${UUID}-ImageFromJson`, Extends: Image, contentType: 'image/svg+xml', @@ -394,7 +395,7 @@ var Images = { // Wrapper around a json file (drawing saves). var Json = new Lang.Class({ - Name: `${Me.uuid}.Json`, + Name: `${UUID}-Json`, _init: function(params) { for (let key in params) diff --git a/helper.js b/helper.js index 70343e4..8616adb 100644 --- a/helper.js +++ b/helper.js @@ -40,11 +40,12 @@ const Tweener = GS_VERSION < '3.33.0' ? imports.ui.tweener : null; const HELPER_ANIMATION_TIME = 0.25; const MEDIA_KEYS_SCHEMA = 'org.gnome.settings-daemon.plugins.media-keys'; const MEDIA_KEYS_KEYS = ['screenshot', 'screenshot-clip', 'area-screenshot', 'area-screenshot-clip']; +const UUID = Me.uuid.replace(/@/gi, '_at_').replace(/[^a-z0-9+_-]/gi, '_'); // DrawingHelper provides the "help osd" (Ctrl + F1) // It uses the same texts as in prefs var DrawingHelper = new Lang.Class({ - Name: `${Me.uuid}.DrawingHelper`, + Name: `${UUID}-DrawingHelper`, Extends: St.ScrollView, _init: function(params, monitor) { diff --git a/menu.js b/menu.js index 2688f27..1753b82 100644 --- a/menu.js +++ b/menu.js @@ -46,6 +46,7 @@ const GS_VERSION = Config.PACKAGE_VERSION; const FONT_FAMILY_STYLE = true; // use 'login-dialog-message-warning' class in order to get GS theme warning color (default: #f57900) const WARNING_COLOR_STYLE_CLASS_NAME = 'login-dialog-message-warning'; +const UUID = Me.uuid.replace(/@/gi, '_at_').replace(/[^a-z0-9+_-]/gi, '_'); const getActor = function(object) { return GS_VERSION < '3.33.0' ? object.actor : object; @@ -139,7 +140,7 @@ var DisplayStrings = { }; var DrawingMenu = new Lang.Class({ - Name: `${Me.uuid}.DrawingMenu`, + Name: `${UUID}-DrawingMenu`, _init: function(area, monitor, drawingTools) { this.area = area; @@ -742,7 +743,7 @@ const updateSubMenuAdjustment = function(itemActor) { // An action button that uses upstream dash item tooltips. const ActionButton = new Lang.Class({ - Name: `${Me.uuid}.DrawingMenuActionButton`, + Name: `${UUID}-DrawingMenuActionButton`, Extends: St.Bin, _labelShowing: false, _resetHoverTimeoutId: 0, @@ -787,7 +788,7 @@ const ActionButton = new Lang.Class({ // based on searchItem.js, https://github.com/leonardo-bartoli/gnome-shell-extension-Recents const Entry = new Lang.Class({ - Name: `${Me.uuid}.DrawingMenuEntry`, + Name: `${UUID}-DrawingMenuEntry`, _init: function(params) { this.params = params; diff --git a/prefs.js b/prefs.js index eb01b24..434c9ab 100644 --- a/prefs.js +++ b/prefs.js @@ -43,11 +43,7 @@ const _GTK = imports.gettext.domain('gtk30').gettext; const MARGIN = 10; const ROWBOX_MARGIN_PARAMS = { margin_top: MARGIN / 2, margin_bottom: MARGIN / 2, margin_left: MARGIN, margin_right: MARGIN }; - -// GTypeName is not sanitized in GS 3.28- -const sanitizeGType = function(name) { - return `Gjs_${name.replace(/@/gi, '_at_').replace(/[^a-z0-9+_-]/gi, '_')}`; -} +const UUID = Me.uuid.replace(/@/gi, '_at_').replace(/[^a-z0-9+_-]/gi, '_'); function init() { Convenience.initTranslations(); @@ -68,8 +64,7 @@ function buildPrefsWidget() { } const TopStack = new GObject.Class({ - Name: `${Me.uuid}.TopStack`, - GTypeName: sanitizeGType(`${Me.uuid}-TopStack`), + Name: `${UUID}-TopStack`, Extends: Gtk.Stack, _init: function(params) { @@ -87,8 +82,7 @@ const TopStack = new GObject.Class({ }); const AboutPage = new GObject.Class({ - Name: `${Me.uuid}.AboutPage`, - GTypeName: sanitizeGType(`${Me.uuid}-AboutPage`), + Name: `${UUID}-AboutPage`, Extends: Gtk.ScrolledWindow, _init: function(params) { @@ -141,8 +135,7 @@ const AboutPage = new GObject.Class({ }); const DrawingPage = new GObject.Class({ - Name: `${Me.uuid}.DrawingPage`, - GTypeName: sanitizeGType(`${Me.uuid}-DrawingPage`), + Name: `${UUID}-DrawingPage`, Extends: Gtk.ScrolledWindow, _init: function(params) { @@ -394,8 +387,7 @@ const DrawingPage = new GObject.Class({ }); const PrefsPage = new GObject.Class({ - Name: `${Me.uuid}.PrefsPage`, - GTypeName: sanitizeGType(`${Me.uuid}-PrefsPage`), + Name: `${UUID}-PrefsPage`, Extends: Gtk.ScrolledWindow, _init: function(params) { @@ -508,8 +500,7 @@ const PrefsPage = new GObject.Class({ }); const Frame = new GObject.Class({ - Name: `${Me.uuid}.Frame`, - GTypeName: sanitizeGType(`${Me.uuid}-Frame`), + Name: `${UUID}-Frame`, Extends: Gtk.Frame, _init: function(params) { @@ -524,8 +515,7 @@ const Frame = new GObject.Class({ }); const PrefRow = new GObject.Class({ - Name: `${Me.uuid}.PrefRow`, - GTypeName: sanitizeGType(`${Me.uuid}-PrefRow`), + Name: `${UUID}-PrefRow`, Extends: Gtk.ListBoxRow, _init: function(params) { @@ -569,8 +559,7 @@ const PrefRow = new GObject.Class({ }); const PixelSpinButton = new GObject.Class({ - Name: `${Me.uuid}.PixelSpinButton`, - GTypeName: sanitizeGType(`${Me.uuid}-PixelSpinButton`), + Name: `${UUID}-PixelSpinButton`, Extends: Gtk.SpinButton, Properties: { 'range': GObject.param_spec_variant('range', 'range', 'GSettings range', @@ -609,8 +598,7 @@ const PixelSpinButton = new GObject.Class({ // A color button that can be easily bound with a color string setting. const ColorStringButton = new GObject.Class({ - Name: `${Me.uuid}.ColorStringButton`, - GTypeName: sanitizeGType(`${Me.uuid}-ColorStringButton`), + Name: `${UUID}-ColorStringButton`, Extends: Gtk.ColorButton, Properties: { 'color-string': GObject.ParamSpec.string('color-string', 'colorString', 'A string that describes the color', @@ -642,8 +630,7 @@ const ColorStringButton = new GObject.Class({ }); const FileChooserButton = new GObject.Class({ - Name: `${Me.uuid}.FileChooserButton`, - GTypeName: sanitizeGType(`${Me.uuid}-FileChooserButton`), + Name: `${UUID}-FileChooserButton`, Extends: Gtk.FileChooserButton, Properties: { 'location': GObject.ParamSpec.string('location', 'location', 'location', @@ -674,8 +661,7 @@ const FileChooserButton = new GObject.Class({ // this code comes from Sticky Notes View by Sam Bull, https://extensions.gnome.org/extension/568/notes/ const KeybindingsWidget = new GObject.Class({ - Name: `${Me.uuid}.KeybindingsWidget`, - GTypeName: sanitizeGType(`${Me.uuid}-KeybindingsWidget`), + Name: `${UUID}-KeybindingsWidget`, Extends: Gtk.Box, _init: function(settingKeys, settings) {