<commit_before># The MIT License (MIT)
#
# Copyright (c) 2015 <NAME>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from __future__ import absolute_import

import time
import re
import logging
import base64
import hashlib
import hmac

import flask

logger = logging.getLogger("flask-secure-cookie")

_UTF8_TYPES = (bytes, type(None))
_signed_value_version_re = re.compile(br"^([1-9][0-9]*)\|(.*)$")

DEFAULT_SIGNED_VALUE_VERSION = 2
DEFAULT_SIGNED_VALUE_MIN_VERSION = 1

if not isinstance(b'', type('')):
    def u(s):
        return s
    unicode_type = str
    basestring_type = str
else:
    def u(s):
        return s.decode('unicode_escape')
    # These names don't exist in py3, so use noqa comments to disable
    # warnings in flake8.
    unicode_type = unicode  # noqa
    basestring_type = basestring  # noqa

def utf8(value):
    """Converts a string argument to a byte string.

    If the argument is already a byte string or None, it is returned unchanged.
    Otherwise it must be a unicode string and is encoded as utf8.
    """
    if isinstance(value, _UTF8_TYPES):
        return value
    if not isinstance(value, unicode_type):
        raise TypeError(
            "Expected bytes, unicode, or None; got %r" % type(value)
        )
    return value.encode("utf-8")



class SecureCookie(object):
    app = None
    cookie_secret = None

    def __init__(self, app=None, cookie_secret=None):
        self.app = app

        if cookie_secret:
            self.cookie_secret = cookie_secret

        if app is not None:
            self.init_app(app)

    def _time_independent_equals(self, a, b):
        if len(a) != len(b):
            return False
        result = 0
        if isinstance(a[0], int):  # python3 byte strings
            for x, y in zip(a, b):
                result |= x ^ y
        else:  # python2
            for x, y in zip(a, b):
                result |= ord(x) ^ ord(y)
        return result == 0

    def _get_version(self, value):
        # Figures out what version value is.  Version 1 did not include an
        # explicit version field and started with arbitrary base64 data,
        # which makes this tricky.
        m = _signed_value_version_re.match(value)
        if m is None:
            version = 1
        else:
            try:
                version = int(m.group(1))
                if version > 999:
                    # Certain payloads from the version-less v1 format may
                    # be parsed as valid integers.  Due to base64 padding
                    # restrictions, this can only happen for numbers whose
                    # length is a multiple of 4, so we can treat all
                    # numbers up to 999 as versions, and for the rest we
                    # fall back to v1 format.
                    version = 1
            except ValueError:
                version = 1
        return version

    def _create_signature_v1(self, secret, *parts):
        hash = hmac.new(self.utf8(secret), digestmod=hashlib.sha1)
        for part in parts:
            hash.update(utf8(part))
        return utf8(hash.hexdigest())

    def _create_signature_v2(self, secret, s):
        hash = hmac.new(utf8(secret), digestmod=hashlib.sha256)
        hash.update(utf8(s))
        return utf8(hash.hexdigest())

    def _decode_signed_value_v1(self, secret, name, value, max_age_days, clock):
        parts = utf8(value).split(b"|")
        if len(parts) != 3:
            return None
        signature = self._create_signature_v1(secret, name, parts[0], parts[1])
        if not self._time_independent_equals(parts[2], signature):
            logger.warning("Invalid cookie signature %r", value)
            return None
        timestamp = int(parts[1])
        if timestamp < clock() - max_age_days * 86400:
            logger.warning("Expired cookie %r", value)
            return None
        if timestamp > clock() + 31 * 86400:
            # _cookie_signature does not hash a delimiter between the
            # parts of the cookie, so an attacker could transfer trailing
            # digits from the payload to the timestamp without altering the
            # signature.  For backwards compatibility, sanity-check timestamp
            # here instead of modifying _cookie_signature.
            logger.warning("Cookie timestamp in future; possible tampering %r",
                            value)
            return None
        if parts[1].startswith(b"0"):<commit_msg>Minor typo fix in _create_signature_v1()<commit_after># The MIT License (MIT)
#
# Copyright (c) 2015 <NAME>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from __future__ import absolute_import

import time
import re
import logging
import base64
import hashlib
import hmac

import flask

logger = logging.getLogger("flask-secure-cookie")

_UTF8_TYPES = (bytes, type(None))
_signed_value_version_re = re.compile(br"^([1-9][0-9]*)\|(.*)$")

DEFAULT_SIGNED_VALUE_VERSION = 2
DEFAULT_SIGNED_VALUE_MIN_VERSION = 1

if not isinstance(b'', type('')):
    def u(s):
        return s
    unicode_type = str
    basestring_type = str
else:
    def u(s):
        return s.decode('unicode_escape')
    # These names don't exist in py3, so use noqa comments to disable
    # warnings in flake8.
    unicode_type = unicode  # noqa
    basestring_type = basestring  # noqa

def utf8(value):
    """Converts a string argument to a byte string.

    If the argument is already a byte string or None, it is returned unchanged.
    Otherwise it must be a unicode string and is encoded as utf8.
    """
    if isinstance(value, _UTF8_TYPES):
        return value
    if not isinstance(value, unicode_type):
        raise TypeError(
            "Expected bytes, unicode, or None; got %r" % type(value)
        )
    return value.encode("utf-8")



class SecureCookie(object):
    app = None
    cookie_secret = None

    def __init__(self, app=None, cookie_secret=None):
        self.app = app

        if cookie_secret:
            self.cookie_secret = cookie_secret

        if app is not None:
            self.init_app(app)

    def _time_independent_equals(self, a, b):
        if len(a) != len(b):
            return False
        result = 0
        if isinstance(a[0], int):  # python3 byte strings
            for x, y in zip(a, b):
                result |= x ^ y
        else:  # python2
            for x, y in zip(a, b):
                result |= ord(x) ^ ord(y)
        return result == 0

    def _get_version(self, value):
        # Figures out what version value is.  Version 1 did not include an
        # explicit version field and started with arbitrary base64 data,
        # which makes this tricky.
        m = _signed_value_version_re.match(value)
        if m is None:
            version = 1
        else:
            try:
                version = int(m.group(1))
                if version > 999:
                    # Certain payloads from the version-less v1 format may
                    # be parsed as valid integers.  Due to base64 padding
                    # restrictions, this can only happen for numbers whose
                    # length is a multiple of 4, so we can treat all
                    # numbers up to 999 as versions, and for the rest we
                    # fall back to v1 format.
                    version = 1
            except ValueError:
                version = 1
        return version

    def _create_signature_v1(self, secret, *parts):
        hash = hmac.new(utf8(secret), digestmod=hashlib.sha1)
        for part in parts:
            hash.update(utf8(part))
        return utf8(hash.hexdigest())

    def _create_signature_v2(self, secret, s):
        hash = hmac.new(utf8(secret), digestmod=hashlib.sha256)
        hash.update(utf8(s))
        return utf8(hash.hexdigest())

    def _decode_signed_value_v1(self, secret, name, value, max_age_days, clock):
        parts = utf8(value).split(b"|")
        if len(parts) != 3:
            return None
        signature = self._create_signature_v1(secret, name, parts[0], parts[1])
        if not self._time_independent_equals(parts[2], signature):
            logger.warning("Invalid cookie signature %r", value)
            return None
        timestamp = int(parts[1])
        if timestamp < clock() - max_age_days * 86400:
            logger.warning("Expired cookie %r", value)
            return None
        if timestamp > clock() + 31 * 86400:
            # _cookie_signature does not hash a delimiter between the
            # parts of the cookie, so an attacker could transfer trailing
            # digits from the payload to the timestamp without altering the
            # signature.  For backwards compatibility, sanity-check timestamp
            # here instead of modifying _cookie_signature.
            logger.warning("Cookie timestamp in future; possible tampering %r",
                            value)
            return None
        if parts[1].startswith(b"0"):
{'fraction_non_alphanumeric': 0.07801094890510948, 'fraction_numerical': 0.01395985401459854, 'mean_word_length': 2.389301175015461, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7035097', 'n_tokens_mistral': 3118, 'n_tokens_neox': 2931, 'n_words': 1169}