Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | # This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
michael@0 | 4 | |
michael@0 | 5 | import os |
michael@0 | 6 | import xml.dom.minidom |
michael@0 | 7 | import StringIO |
michael@0 | 8 | |
michael@0 | 9 | RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
michael@0 | 10 | EM_NS = "http://www.mozilla.org/2004/em-rdf#" |
michael@0 | 11 | |
michael@0 | 12 | class RDF(object): |
michael@0 | 13 | def __str__(self): |
michael@0 | 14 | # real files have an .encoding attribute and use it when you |
michael@0 | 15 | # write() unicode into them: they read()/write() unicode and |
michael@0 | 16 | # put encoded bytes in the backend file. StringIO objects |
michael@0 | 17 | # read()/write() unicode and put unicode in the backing store, |
michael@0 | 18 | # so we must encode the output of getvalue() to get a |
michael@0 | 19 | # bytestring. (cStringIO objects are weirder: they effectively |
michael@0 | 20 | # have .encoding hardwired to "ascii" and put only bytes in |
michael@0 | 21 | # the backing store, so we can't use them here). |
michael@0 | 22 | # |
michael@0 | 23 | # The encoding= argument to dom.writexml() merely sets the XML header's |
michael@0 | 24 | # encoding= attribute. It still writes unencoded unicode to the output file, |
michael@0 | 25 | # so we have to encode it for real afterwards. |
michael@0 | 26 | # |
michael@0 | 27 | # Also see: https://bugzilla.mozilla.org/show_bug.cgi?id=567660 |
michael@0 | 28 | |
michael@0 | 29 | buf = StringIO.StringIO() |
michael@0 | 30 | self.dom.writexml(buf, encoding="utf-8") |
michael@0 | 31 | return buf.getvalue().encode('utf-8') |
michael@0 | 32 | |
michael@0 | 33 | class RDFUpdate(RDF): |
michael@0 | 34 | def __init__(self): |
michael@0 | 35 | impl = xml.dom.minidom.getDOMImplementation() |
michael@0 | 36 | self.dom = impl.createDocument(RDF_NS, "RDF", None) |
michael@0 | 37 | self.dom.documentElement.setAttribute("xmlns", RDF_NS) |
michael@0 | 38 | self.dom.documentElement.setAttribute("xmlns:em", EM_NS) |
michael@0 | 39 | |
michael@0 | 40 | def _make_node(self, name, value, parent): |
michael@0 | 41 | elem = self.dom.createElement(name) |
michael@0 | 42 | elem.appendChild(self.dom.createTextNode(value)) |
michael@0 | 43 | parent.appendChild(elem) |
michael@0 | 44 | return elem |
michael@0 | 45 | |
michael@0 | 46 | def add(self, manifest, update_link): |
michael@0 | 47 | desc = self.dom.createElement("Description") |
michael@0 | 48 | desc.setAttribute( |
michael@0 | 49 | "about", |
michael@0 | 50 | "urn:mozilla:extension:%s" % manifest.get("em:id") |
michael@0 | 51 | ) |
michael@0 | 52 | self.dom.documentElement.appendChild(desc) |
michael@0 | 53 | |
michael@0 | 54 | updates = self.dom.createElement("em:updates") |
michael@0 | 55 | desc.appendChild(updates) |
michael@0 | 56 | |
michael@0 | 57 | seq = self.dom.createElement("Seq") |
michael@0 | 58 | updates.appendChild(seq) |
michael@0 | 59 | |
michael@0 | 60 | li = self.dom.createElement("li") |
michael@0 | 61 | seq.appendChild(li) |
michael@0 | 62 | |
michael@0 | 63 | li_desc = self.dom.createElement("Description") |
michael@0 | 64 | li.appendChild(li_desc) |
michael@0 | 65 | |
michael@0 | 66 | self._make_node("em:version", manifest.get("em:version"), |
michael@0 | 67 | li_desc) |
michael@0 | 68 | |
michael@0 | 69 | apps = manifest.dom.documentElement.getElementsByTagName( |
michael@0 | 70 | "em:targetApplication" |
michael@0 | 71 | ) |
michael@0 | 72 | |
michael@0 | 73 | for app in apps: |
michael@0 | 74 | target_app = self.dom.createElement("em:targetApplication") |
michael@0 | 75 | li_desc.appendChild(target_app) |
michael@0 | 76 | |
michael@0 | 77 | ta_desc = self.dom.createElement("Description") |
michael@0 | 78 | target_app.appendChild(ta_desc) |
michael@0 | 79 | |
michael@0 | 80 | for name in ["em:id", "em:minVersion", "em:maxVersion"]: |
michael@0 | 81 | elem = app.getElementsByTagName(name)[0] |
michael@0 | 82 | self._make_node(name, elem.firstChild.nodeValue, ta_desc) |
michael@0 | 83 | |
michael@0 | 84 | self._make_node("em:updateLink", update_link, ta_desc) |
michael@0 | 85 | |
michael@0 | 86 | class RDFManifest(RDF): |
michael@0 | 87 | def __init__(self, path): |
michael@0 | 88 | self.dom = xml.dom.minidom.parse(path) |
michael@0 | 89 | |
michael@0 | 90 | def set(self, property, value): |
michael@0 | 91 | elements = self.dom.documentElement.getElementsByTagName(property) |
michael@0 | 92 | if not elements: |
michael@0 | 93 | raise ValueError("Element with value not found: %s" % property) |
michael@0 | 94 | if not elements[0].firstChild: |
michael@0 | 95 | elements[0].appendChild(self.dom.createTextNode(value)) |
michael@0 | 96 | else: |
michael@0 | 97 | elements[0].firstChild.nodeValue = value |
michael@0 | 98 | |
michael@0 | 99 | def get(self, property, default=None): |
michael@0 | 100 | elements = self.dom.documentElement.getElementsByTagName(property) |
michael@0 | 101 | if not elements: |
michael@0 | 102 | return default |
michael@0 | 103 | return elements[0].firstChild.nodeValue |
michael@0 | 104 | |
michael@0 | 105 | def remove(self, property): |
michael@0 | 106 | elements = self.dom.documentElement.getElementsByTagName(property) |
michael@0 | 107 | if not elements: |
michael@0 | 108 | return True |
michael@0 | 109 | else: |
michael@0 | 110 | for i in elements: |
michael@0 | 111 | i.parentNode.removeChild(i); |
michael@0 | 112 | |
michael@0 | 113 | return True; |
michael@0 | 114 | |
michael@0 | 115 | def gen_manifest(template_root_dir, target_cfg, jid, |
michael@0 | 116 | update_url=None, bootstrap=True, enable_mobile=False): |
michael@0 | 117 | install_rdf = os.path.join(template_root_dir, "install.rdf") |
michael@0 | 118 | manifest = RDFManifest(install_rdf) |
michael@0 | 119 | dom = manifest.dom |
michael@0 | 120 | |
michael@0 | 121 | manifest.set("em:id", jid) |
michael@0 | 122 | manifest.set("em:version", |
michael@0 | 123 | target_cfg.get('version', '1.0')) |
michael@0 | 124 | manifest.set("em:name", |
michael@0 | 125 | target_cfg.get('title', target_cfg.get('fullName', target_cfg['name']))) |
michael@0 | 126 | manifest.set("em:description", |
michael@0 | 127 | target_cfg.get("description", "")) |
michael@0 | 128 | manifest.set("em:creator", |
michael@0 | 129 | target_cfg.get("author", "")) |
michael@0 | 130 | manifest.set("em:bootstrap", str(bootstrap).lower()) |
michael@0 | 131 | # XPIs remain packed by default, but package.json can override that. The |
michael@0 | 132 | # RDF format accepts "true" as True, anything else as False. We expect |
michael@0 | 133 | # booleans in the .json file, not strings. |
michael@0 | 134 | manifest.set("em:unpack", "true" if target_cfg.get("unpack") else "false") |
michael@0 | 135 | |
michael@0 | 136 | for translator in target_cfg.get("translators", [ ]): |
michael@0 | 137 | elem = dom.createElement("em:translator"); |
michael@0 | 138 | elem.appendChild(dom.createTextNode(translator)) |
michael@0 | 139 | dom.documentElement.getElementsByTagName("Description")[0].appendChild(elem) |
michael@0 | 140 | |
michael@0 | 141 | for contributor in target_cfg.get("contributors", [ ]): |
michael@0 | 142 | elem = dom.createElement("em:contributor"); |
michael@0 | 143 | elem.appendChild(dom.createTextNode(contributor)) |
michael@0 | 144 | dom.documentElement.getElementsByTagName("Description")[0].appendChild(elem) |
michael@0 | 145 | |
michael@0 | 146 | if update_url: |
michael@0 | 147 | manifest.set("em:updateURL", update_url) |
michael@0 | 148 | else: |
michael@0 | 149 | manifest.remove("em:updateURL") |
michael@0 | 150 | |
michael@0 | 151 | if target_cfg.get("preferences"): |
michael@0 | 152 | manifest.set("em:optionsType", "2") |
michael@0 | 153 | else: |
michael@0 | 154 | manifest.remove("em:optionsType") |
michael@0 | 155 | |
michael@0 | 156 | if enable_mobile: |
michael@0 | 157 | target_app = dom.createElement("em:targetApplication") |
michael@0 | 158 | dom.documentElement.getElementsByTagName("Description")[0].appendChild(target_app) |
michael@0 | 159 | |
michael@0 | 160 | ta_desc = dom.createElement("Description") |
michael@0 | 161 | target_app.appendChild(ta_desc) |
michael@0 | 162 | |
michael@0 | 163 | elem = dom.createElement("em:id") |
michael@0 | 164 | elem.appendChild(dom.createTextNode("{aa3c5121-dab2-40e2-81ca-7ea25febc110}")) |
michael@0 | 165 | ta_desc.appendChild(elem) |
michael@0 | 166 | |
michael@0 | 167 | elem = dom.createElement("em:minVersion") |
michael@0 | 168 | elem.appendChild(dom.createTextNode("26.0")) |
michael@0 | 169 | ta_desc.appendChild(elem) |
michael@0 | 170 | |
michael@0 | 171 | elem = dom.createElement("em:maxVersion") |
michael@0 | 172 | elem.appendChild(dom.createTextNode("30.0a1")) |
michael@0 | 173 | ta_desc.appendChild(elem) |
michael@0 | 174 | |
michael@0 | 175 | if target_cfg.get("homepage"): |
michael@0 | 176 | manifest.set("em:homepageURL", target_cfg.get("homepage")) |
michael@0 | 177 | else: |
michael@0 | 178 | manifest.remove("em:homepageURL") |
michael@0 | 179 | |
michael@0 | 180 | return manifest |
michael@0 | 181 | |
michael@0 | 182 | if __name__ == "__main__": |
michael@0 | 183 | print "Running smoke test." |
michael@0 | 184 | root = os.path.join(os.path.dirname(__file__), '../../app-extension') |
michael@0 | 185 | manifest = gen_manifest(root, {'name': 'test extension'}, |
michael@0 | 186 | 'fakeid', 'http://foo.com/update.rdf') |
michael@0 | 187 | update = RDFUpdate() |
michael@0 | 188 | update.add(manifest, "https://foo.com/foo.xpi") |
michael@0 | 189 | exercise_str = str(manifest) + str(update) |
michael@0 | 190 | for tagname in ["em:targetApplication", "em:version", "em:id"]: |
michael@0 | 191 | if not len(update.dom.getElementsByTagName(tagname)): |
michael@0 | 192 | raise Exception("tag does not exist: %s" % tagname) |
michael@0 | 193 | if not update.dom.getElementsByTagName(tagname)[0].firstChild: |
michael@0 | 194 | raise Exception("tag has no children: %s" % tagname) |
michael@0 | 195 | print "Success!" |