diff options
author | Paul Kehrer <paul.l.kehrer@gmail.com> | 2017-10-11 11:47:46 +0800 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2017-10-10 23:47:46 -0400 |
commit | 1b43b51599e4a3b39662b069af0140bf24ac3a43 (patch) | |
tree | 538c53bf09577ba436587ccfa2b53db7a1d8ef24 /src/cryptography/x509 | |
parent | d3f73e0de5bf407f375c18b94f3f9535439ece3d (diff) | |
download | cryptography-1b43b51599e4a3b39662b069af0140bf24ac3a43.tar.gz cryptography-1b43b51599e4a3b39662b069af0140bf24ac3a43.tar.bz2 cryptography-1b43b51599e4a3b39662b069af0140bf24ac3a43.zip |
backwards incompatible change to UniformResourceIdentifier (#3954)
* backwards incompatible change to UniformResourceIdentifier
During this release cycle we decided to officially deprecate passing
U-labels to our GeneralName constructors. At first we tried changing
this in a purely backwards compatible way but get_values_for_type made
that untenable. This PR modifies URI to accept two types:
U-label strings (which raises a deprecation warning) and A-label strings
(the new preferred type). There is also a constructor for URI
that bypasses validation so we can parse garbage out of certificates
(and round trip it if necessary)
* nonsense empty commit 2.6 and codecov are the worst
Diffstat (limited to 'src/cryptography/x509')
-rw-r--r-- | src/cryptography/x509/general_name.py | 75 |
1 files changed, 19 insertions, 56 deletions
diff --git a/src/cryptography/x509/general_name.py b/src/cryptography/x509/general_name.py index 6f7fa7a7..776219e2 100644 --- a/src/cryptography/x509/general_name.py +++ b/src/cryptography/x509/general_name.py @@ -163,30 +163,29 @@ class UniformResourceIdentifier(object): def __init__(self, value): if isinstance(value, six.text_type): try: - value = value.encode("ascii") + value.encode("ascii") except UnicodeEncodeError: value = self._idna_encode(value) warnings.warn( - "UniformResourceIdentifier values should be passed as " - "bytes with the hostname idna encoded, not strings. " - "Support for passing unicode strings will be removed in a " - "future version.", - utils.DeprecatedIn21, - stacklevel=2, - ) - else: - warnings.warn( - "UniformResourceIdentifier values should be passed as " - "bytes with the hostname idna encoded, not strings. " - "Support for passing unicode strings will be removed in a " - "future version.", + "URI values should be passed as an A-label string. " + "This means unicode characters should be encoded via " + "idna. Support for passing unicode strings (aka U-label) " + " will be removed in a future version.", utils.DeprecatedIn21, stacklevel=2, ) - elif not isinstance(value, bytes): - raise TypeError("value must be bytes") + else: + raise TypeError("value must be string") + + self._value = value - self._bytes_value = value + value = utils.read_only_property("_value") + + @classmethod + def _init_without_validation(cls, value): + instance = cls.__new__(cls) + instance._value = value + return instance def _idna_encode(self, value): parsed = urllib_parse.urlparse(value) @@ -208,58 +207,22 @@ class UniformResourceIdentifier(object): parsed.params, parsed.query, parsed.fragment - )).encode("ascii") - - @property - def value(self): - warnings.warn( - "UniformResourceIdentifier.bytes_value should be used instead of " - "UniformResourceIdentifier.value; it contains the name as raw " - "bytes, instead of as an idna-decoded unicode string. " - "UniformResourceIdentifier.value will be removed in a future " - "version.", - utils.DeprecatedIn21, - stacklevel=2 - ) - parsed = urllib_parse.urlparse(self.bytes_value) - if not parsed.hostname: - # There's no idna here so we can immediately return - return self.bytes_value.decode("utf-8") - elif parsed.port: - netloc = idna.decode(parsed.hostname) + ":{0}".format(parsed.port) - else: - netloc = idna.decode(parsed.hostname) - - # Note that building a URL in this fashion means it should be - # semantically indistinguishable from the original but is not - # guaranteed to be exactly the same. - return urllib_parse.urlunparse(( - parsed.scheme.decode('utf8'), - netloc, - parsed.path.decode('utf8'), - parsed.params.decode('utf8'), - parsed.query.decode('utf8'), - parsed.fragment.decode('utf8') )) - bytes_value = utils.read_only_property("_bytes_value") - def __repr__(self): - return "<UniformResourceIdentifier(bytes_value={0!r})>".format( - self.bytes_value - ) + return "<UniformResourceIdentifier(value={0!r})>".format(self.value) def __eq__(self, other): if not isinstance(other, UniformResourceIdentifier): return NotImplemented - return self.bytes_value == other.bytes_value + return self.value == other.value def __ne__(self, other): return not self == other def __hash__(self): - return hash(self.bytes_value) + return hash(self.value) @utils.register_interface(GeneralName) |