Fix extension id calculation to take into account Windows encoding.
BUG=243532 TEST=updated and ran telemetry unit tests NOTRY=true Review URL: https://chromiumcodereview.appspot.com/16346003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204380 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
tools
@@ -75,7 +75,7 @@ def GetPublicKeyPacked(f):
|
||||
pub_key = f.read(pub_key_len_bytes)
|
||||
return pub_key
|
||||
|
||||
def GetPublicKeyFromPath(filepath):
|
||||
def GetPublicKeyFromPath(filepath, is_win_path=False):
|
||||
# Normalize the path for windows to have capital drive letters.
|
||||
# We intentionally don't check if sys.platform == 'win32' and just
|
||||
# check if this looks like drive letter so that we can test this
|
||||
@@ -83,7 +83,15 @@ def GetPublicKeyFromPath(filepath):
|
||||
if (len(filepath) >= 2 and
|
||||
filepath[0].islower() and
|
||||
filepath[1] == ':'):
|
||||
return filepath[0].upper() + filepath[1:]
|
||||
filepath = filepath[0].upper() + filepath[1:]
|
||||
|
||||
# On Windows, filepaths are encoded using UTF-16, little endian byte order,
|
||||
# using "wide characters" that are 16 bits in size. On POSIX systems, the
|
||||
# encoding is generally UTF-8, which has the property of being equivalent to
|
||||
# ASCII when only ASCII characters are in the path.
|
||||
if is_win_path:
|
||||
filepath = filepath.encode('utf-16le')
|
||||
|
||||
return filepath
|
||||
|
||||
def GetPublicKeyUnpacked(f, filepath):
|
||||
@@ -102,9 +110,10 @@ def HasPublicKey(filename):
|
||||
return 'key' in manifest
|
||||
return False
|
||||
|
||||
def GetPublicKey(filename, from_file_path):
|
||||
def GetPublicKey(filename, from_file_path, is_win_path=False):
|
||||
if from_file_path:
|
||||
return GetPublicKeyFromPath(filename)
|
||||
return GetPublicKeyFromPath(
|
||||
filename, is_win_path=is_win_path)
|
||||
|
||||
pub_key = ''
|
||||
if os.path.isdir(filename):
|
||||
@@ -119,13 +128,13 @@ def GetPublicKey(filename, from_file_path):
|
||||
f.close()
|
||||
return pub_key
|
||||
|
||||
def GetCRXHash(filename, from_file_path=False):
|
||||
pub_key = GetPublicKey(filename, from_file_path)
|
||||
def GetCRXHash(filename, from_file_path=False, is_win_path=False):
|
||||
pub_key = GetPublicKey(filename, from_file_path, is_win_path=is_win_path)
|
||||
pub_key_hash = hashlib.sha256(pub_key).digest()
|
||||
return HexTo256(pub_key_hash)
|
||||
|
||||
def GetCRXAppID(filename, from_file_path=False):
|
||||
pub_key = GetPublicKey(filename, from_file_path)
|
||||
def GetCRXAppID(filename, from_file_path=False, is_win_path=False):
|
||||
pub_key = GetPublicKey(filename, from_file_path, is_win_path=is_win_path)
|
||||
pub_key_hash = hashlib.sha256(pub_key).digest()
|
||||
# AppID is the MPDecimal of only the first 128 bits of the hash.
|
||||
return HexToMPDecimal(pub_key_hash[:128/8])
|
||||
|
@@ -63,13 +63,22 @@ class CrxIdUnittest(unittest.TestCase):
|
||||
self.assertEqual(crx_id.GetCRXAppID('/tmp/temp_extension',
|
||||
from_file_path=True),
|
||||
'ajbbicncdkdlchpjplgjaglppbcbmaji')
|
||||
|
||||
def testFromWindowsPath(self):
|
||||
self.assertEqual(crx_id.GetCRXAppID(r'D:\Documents\chrome\test_extension',
|
||||
from_file_path=True,
|
||||
is_win_path=True),
|
||||
'fegemedmbnhglnecjgbdhekaghkccplm')
|
||||
|
||||
# Test drive letter normalization.
|
||||
kWinPathId = 'popnagglbbhjlobnnbcjnckakjoegnjp'
|
||||
self.assertEqual(crx_id.GetCRXAppID('c:\temp_extension',
|
||||
from_file_path=True),
|
||||
kWinPathId = 'aiinlcdagjihibappcdnnhcccdokjlaf'
|
||||
self.assertEqual(crx_id.GetCRXAppID(r'c:\temp_extension',
|
||||
from_file_path=True,
|
||||
is_win_path=True),
|
||||
kWinPathId)
|
||||
self.assertEqual(crx_id.GetCRXAppID('C:\temp_extension',
|
||||
from_file_path=True),
|
||||
self.assertEqual(crx_id.GetCRXAppID(r'C:\temp_extension',
|
||||
from_file_path=True,
|
||||
is_win_path=True),
|
||||
kWinPathId)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@@ -12,7 +12,7 @@ class MissingPublicKeyException(Exception):
|
||||
pass
|
||||
|
||||
class ExtensionToLoad(object):
|
||||
def __init__(self, path, is_component=False):
|
||||
def __init__(self, path, browser_type, is_component=False):
|
||||
if not os.path.isdir(path):
|
||||
raise ExtensionPathNonExistentException(
|
||||
'Extension path not a directory %s' % path)
|
||||
@@ -23,6 +23,14 @@ class ExtensionToLoad(object):
|
||||
raise MissingPublicKeyException(
|
||||
'Component extension %s must have a public key' % path)
|
||||
|
||||
# It is possible that we are running telemetry on Windows targeting
|
||||
# a remote CrOS or Android device. In this case, we need the
|
||||
# browser_type argument to determine how we should encode
|
||||
# the extension path.
|
||||
self._is_win = (os.name == 'nt'
|
||||
and not (browser_type.startswith('android')
|
||||
or browser_type.startswith('cros')))
|
||||
|
||||
@property
|
||||
def extension_id(self):
|
||||
"""Unique extension id of this extension."""
|
||||
@@ -31,8 +39,10 @@ class ExtensionToLoad(object):
|
||||
return crx_id.GetCRXAppID(os.path.realpath(self._path))
|
||||
else:
|
||||
# Calculate extension id based on the path on the device.
|
||||
return crx_id.GetCRXAppID(os.path.realpath(self._local_path),
|
||||
from_file_path=True)
|
||||
return crx_id.GetCRXAppID(
|
||||
os.path.realpath(self._local_path),
|
||||
from_file_path=True,
|
||||
is_win_path=self._is_win)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
|
@@ -16,9 +16,10 @@ class ExtensionTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
extension_path = os.path.join(os.path.dirname(__file__),
|
||||
'..', '..', 'unittest_data', 'simple_extension')
|
||||
load_extension = extension_to_load.ExtensionToLoad(extension_path)
|
||||
|
||||
options = options_for_unittests.GetCopy()
|
||||
load_extension = extension_to_load.ExtensionToLoad(
|
||||
extension_path, options.browser_type)
|
||||
options.extensions_to_load = [load_extension]
|
||||
browser_to_create = browser_finder.FindBrowser(options)
|
||||
|
||||
@@ -60,15 +61,18 @@ class NonExistentExtensionTest(unittest.TestCase):
|
||||
"""Test that a non-existent extension path will raise an exception."""
|
||||
extension_path = os.path.join(os.path.dirname(__file__),
|
||||
'..', '..', 'unittest_data', 'foo')
|
||||
options = options_for_unittests.GetCopy()
|
||||
self.assertRaises(extension_to_load.ExtensionPathNonExistentException,
|
||||
lambda: extension_to_load.ExtensionToLoad(extension_path))
|
||||
lambda: extension_to_load.ExtensionToLoad(
|
||||
extension_path, options.browser_type))
|
||||
|
||||
def testExtensionNotLoaded(self):
|
||||
"""Querying an extension that was not loaded will return None"""
|
||||
extension_path = os.path.join(os.path.dirname(__file__),
|
||||
'..', '..', 'unittest_data', 'simple_extension')
|
||||
load_extension = extension_to_load.ExtensionToLoad(extension_path)
|
||||
options = options_for_unittests.GetCopy()
|
||||
load_extension = extension_to_load.ExtensionToLoad(
|
||||
extension_path, options.browser_type)
|
||||
browser_to_create = browser_finder.FindBrowser(options)
|
||||
with browser_to_create.Create() as b:
|
||||
if b.supports_extensions:
|
||||
@@ -88,9 +92,10 @@ class MultipleExtensionTest(unittest.TestCase):
|
||||
for d in self._extension_dirs:
|
||||
shutil.copy(manifest_path, d)
|
||||
shutil.copy(script_path, d)
|
||||
self._extensions_to_load = [extension_to_load.ExtensionToLoad(d)
|
||||
for d in self._extension_dirs]
|
||||
options = options_for_unittests.GetCopy()
|
||||
self._extensions_to_load = [extension_to_load.ExtensionToLoad(
|
||||
d, options.browser_type)
|
||||
for d in self._extension_dirs]
|
||||
options.extensions_to_load = self._extensions_to_load
|
||||
browser_to_create = browser_finder.FindBrowser(options)
|
||||
self._browser = None
|
||||
@@ -125,9 +130,10 @@ class ComponentExtensionTest(unittest.TestCase):
|
||||
def testComponentExtensionBasic(self):
|
||||
extension_path = os.path.join(os.path.dirname(__file__),
|
||||
'..', '..', 'unittest_data', 'component_extension')
|
||||
load_extension = extension_to_load.ExtensionToLoad(extension_path, True)
|
||||
|
||||
options = options_for_unittests.GetCopy()
|
||||
load_extension = extension_to_load.ExtensionToLoad(
|
||||
extension_path, options.browser_type, is_component=True)
|
||||
|
||||
options.extensions_to_load = [load_extension]
|
||||
browser_to_create = browser_finder.FindBrowser(options)
|
||||
if not browser_to_create:
|
||||
@@ -144,6 +150,9 @@ class ComponentExtensionTest(unittest.TestCase):
|
||||
# simple_extension does not have a public key.
|
||||
extension_path = os.path.join(os.path.dirname(__file__),
|
||||
'..', '..', 'unittest_data', 'simple_extension')
|
||||
options = options_for_unittests.GetCopy()
|
||||
self.assertRaises(extension_to_load.MissingPublicKeyException,
|
||||
lambda: extension_to_load.ExtensionToLoad(extension_path,
|
||||
True))
|
||||
lambda: extension_to_load.ExtensionToLoad(
|
||||
extension_path,
|
||||
browser_type=options.browser_type,
|
||||
is_component=True))
|
||||
|
Reference in New Issue
Block a user