From 6c7f18a72fe6e362d6ee27018005f6ca0a7c58ff Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Thu, 7 Jul 2016 15:09:30 -0400 Subject: [PATCH] Add filtering for lengths for padding/margin/border/outline/font-size, and handle things like padding-top, etc. Resolves issue #1182 --- unpacked/extensions/Safe.js | 88 ++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 6 deletions(-) diff --git a/unpacked/extensions/Safe.js b/unpacked/extensions/Safe.js index df659bafe..0fc2455a8 100644 --- a/unpacked/extensions/Safe.js +++ b/unpacked/extensions/Safe.js @@ -43,6 +43,7 @@ }, sizeMin: .7, // \scriptsize sizeMax: 1.44, // \large + lengthMax: 3, // largest padding/border/margin, etc. in em's safeProtocols: { http: true, https: true, @@ -86,6 +87,40 @@ noUndefined: false, unicode: true, verb: true + }, + // + // CSS styles that have Top/Right/Bottom/Left versions + // + styleParts: { + border: true, + padding: true, + margin: true, + outline: true + }, + // + // CSS styles that are lengths needing max/min testing + // A string value means test that style value; + // An array gives [min,max] in em's + // Otherwise use [-lengthMax,lengthMax] from above + // + styleLengths: { + borderTop: "borderTopWidth", + borderRight: "borderRightWidth", + borderBottom: "borderBottomWidth", + borderLeft: "borderLeftWidth", + paddingTop: true, + paddingRight: true, + paddingBottom: true, + paddingLeft: true, + marginTop: true, + marginRight: true, + marginBottom: true, + marginLeft: true, + outlineTop: true, + outlineRight: true, + outlineBottom: true, + outlineLeft: true, + fontSize: [.7,1.44] } }); @@ -149,14 +184,23 @@ // // Set the div1 styles to the given styles, and clear div2 // - var STYLE1 = this.div1.style, STYLE2 = this.div2.style; + var STYLE1 = this.div1.style, STYLE2 = this.div2.style, value; STYLE1.cssText = styles; STYLE2.cssText = ""; // // Check each allowed style and transfer OK ones to div2 + // If the style has Top/Right/Bottom/Left, look at all four separately // for (var name in CONFIG.safeStyles) {if (CONFIG.safeStyles.hasOwnProperty(name)) { - var value = this.filterStyle(name,STYLE1[name]); - if (value != null) {STYLE2[name] = value} + if (CONFIG.styleParts[name]) { + for (var i = 0; i < 4; i++) { + var NAME = name+["Top","Right","Bottom","Left"][i] + value = this.filterStyle(NAME,STYLE1); + if (value) {STYLE2[NAME] = value} + } + } else { + value = this.filterStyle(name,STYLE1); + if (value) {STYLE2[name] = value} + } }} // // Return the div2 style string @@ -168,11 +212,43 @@ // // Filter an individual name:value style pair // - filterStyle: function (name,value) { - if (typeof value !== "string") {return null} + filterStyle: function (name,styles) { + var value = styles[name]; + if (typeof value !== "string" || value === "") {return null} if (value.match(/^\s*expression/)) {return null} if (value.match(/javascript:/)) {return null} - return (CONFIG.safeStyles[name] ? value : null); + var NAME = name.replace(/Top|Right|Left|Bottom/,""); + if (!CONFIG.safeStyles[name] && !CONFIG.safeStyles[NAME]) {return null} + if (!CONFIG.styleLengths[name]) {return value} + return (this.filterStyleLength(name,value,styles) ? value : null); + }, + filterStyleLength: function (name,value,styles) { + if (typeof CONFIG.styleLengths[name] === "string") value = styles[CONFIG.styleLengths[name]]; + value = this.length2em(value); + if (value == null) return false; + var mM = [-CONFIG.lengthMax,CONFIG.lengthMax]; + if (CONFIG.styleLengths[name] instanceof Array) mM = CONFIG.styleLengths[name]; + return (value >= mM[0] && value <= mM[1]); + }, + // + // Conversion of units to em's + // + unit2em: { + em: 1, + ex: .5, // assume 1ex = .5em + ch: .5, // assume 1ch = .5em + rem: 1, // assume 1rem = 1em + px: 1/16, // assume 1em = 16px + mm: 96/25.4/16, // 25.4mm = 96px + cm: 96/2.54/16, // 2.54cm = 96px + in: 96/16, // 1in = 96px + pt: 96/72/16, // 72pt = 1in + pc: 96/6/16 // 1pc = 12pt + }, + length2em: function (value) { + var match = value.match(/(.+)(em|ex|ch|rem|px|mm|cm|in|pt|pc)/); + if (!match) return null; + return parseFloat(match[1])*this.unit2em[match[2]]; }, //