Repository: square/okhttp
File: okhttp/src/jvmMain/kotlin/okhttp3/Cookie.kt (Kotlin)

Code before:
      if (domain == null) {
        domain = urlHost
      } else if (!domainMatch(urlHost, domain)) {
        return null // No domain match? This is either incompetence or malice!
      }

      // If the domain is a suffix of the url host, it must not be a public suffix.
      if (urlHost.length != domain.length &&
        PublicSuffixDatabase.get().getEffectiveTldPlusOne(domain) == null) {
        return null
      }

      // If the path is absent or didn't start with '/', use the default path. It's a string like
      // '/foo/bar' for a URL like 'http://example.com/foo/bar/baz'. It always starts with '/'.
      if (path == null || !path.startsWith("/")) {
        val encodedPath = url.encodedPath
        val lastSlash = encodedPath.lastIndexOf('/')
        path = if (lastSlash != 0) encodedPath.substring(0, lastSlash) else "/"
      }

      // If SameSite is absent or not a valid option, use the default value.
      if (sameSite == null) {
        sameSite = "lax"
      }

      // If SameSite is set to `None`, Secure must be true
      if (sameSite.lowercase() == "none" && !secureOnly) {
        secureOnly = true
      }

      return Cookie(cookieName, cookieValue, expiresAt, domain, path, secureOnly, httpOnly,
        persistent, hostOnly, sameSite)
    }

    /** Parse a date as specified in RFC 6265, section 5.1.1. */
    private fun parseExpires(s: String, pos: Int, limit: Int): Long {
      var pos = pos
      pos = dateCharacterOffset(s, pos, limit, false)

      var hour = -1
      var minute = -1
      var second = -1
      var dayOfMonth = -1
      var month = -1
      var year = -1
      val matcher = TIME_PATTERN.matcher(s)

      while (pos < limit) {
        val end = dateCharacterOffset(s, pos + 1, limit, true)
        matcher.region(pos, end)


Review comment (suggestion):
I don’t think we should do this. The parsed `Cookie`’s job is to represent what was encoded only. If the user wants to break the rules, that’s not our business at this layer.

Code after:
        expiresAt = currentTimeMillis + deltaMilliseconds
        if (expiresAt < currentTimeMillis || expiresAt > MAX_DATE) {
          expiresAt = MAX_DATE // Handle overflow & limit the date range.
        }
      }

      // If the domain is present, it must domain match. Otherwise we have a host-only cookie.
      val urlHost = url.host
      if (domain == null) {
        domain = urlHost
      } else if (!domainMatch(urlHost, domain)) {
        return null // No domain match? This is either incompetence or malice!
      }

      // If the domain is a suffix of the url host, it must not be a public suffix.
      if (urlHost.length != domain.length &&
        PublicSuffixDatabase.get().getEffectiveTldPlusOne(domain) == null) {
        return null
      }

      // If the path is absent or didn't start with '/', use the default path. It's a string like
      // '/foo/bar' for a URL like 'http://example.com/foo/bar/baz'. It always starts with '/'.
      if (path == null || !path.startsWith("/")) {
        val encodedPath = url.encodedPath
        val lastSlash = encodedPath.lastIndexOf('/')
        path = if (lastSlash != 0) encodedPath.substring(0, lastSlash) else "/"
      }

      return Cookie(cookieName, cookieValue, expiresAt, domain, path, secureOnly, httpOnly,
        persistent, hostOnly, sameSite)
    }

    /** Parse a date as specified in RFC 6265, section 5.1.1. */
    private fun parseExpires(s: String, pos: Int, limit: Int): Long {
      var pos = pos
      pos = dateCharacterOffset(s, pos, limit, false)

      var hour = -1
      var minute = -1
      var second = -1
      var dayOfMonth = -1
      var month = -1
      var year = -1
      val matcher = TIME_PATTERN.matcher(s)

      while (pos < limit) {
        val end = dateCharacterOffset(s, pos + 1, limit, true)
        matcher.region(pos, end)

        when {
          hour == -1 && matcher.usePattern(TIME_PATTERN).matches() -> {