| #! /bin/bash | |
| # | |
| # Copyright (c) 2022 Apple Inc. All rights reserved. | |
| # | |
| # The 5-tuple version string scheme is a[.b[.c[.d[.e]]]], where | |
| # | |
| # 0 < a ≤ 18446743 | |
| # 0 ≤ b ≤ 999 | |
| # 0 ≤ c ≤ 999 | |
| # 0 ≤ d ≤ 999 | |
| # 0 ≤ e ≤ 999 | |
| # | |
| # mDNSResponder currently encodes version strings as 32-bit unsigned integers. This only allows room for the three | |
| # most significant fields if the following encoding formula is used: (a × 1000000) + (b × 1000) + c. | |
| # | |
| # Note that when b = c = 999, the largest possible 32-bit unsigned integer is 4293999999, therefore 0 < a ≤ 4293 | |
| # must hold. As a starts to get close to surpassing 4293, mDNSResponder may need to start encoding version strings | |
| # using a wider integer type. | |
| declare -r major_max=4293 | |
| declare -r other_max=999 | |
| declare -r version_string="${1}" | |
| valid=false | |
| if [[ ${version_string} =~ ^[0-9]+(\.[0-9]+){0,4}$ ]]; then | |
| fields=(${version_string//./ }) | |
| major="${fields[0]}" | |
| if (( ( major > 0 ) && ( major <= major_max ) )); then | |
| malformed=false | |
| for other_field in "${fields[@]:1}"; do | |
| if (( other_field > other_max )); then | |
| malformed=true | |
| break | |
| fi | |
| done | |
| if ! "${malformed}"; then | |
| valid=true | |
| fi | |
| fi | |
| fi | |
| if "${valid}"; then | |
| result=$( printf '%u%03u%03u' "${fields[0]:-0}" "${fields[1]:-0}" "${fields[2]:-0}" ) | |
| else | |
| result=$( printf '%u%03u%03u' "${major_max}" "${other_max}" "${other_max}" ) | |
| fi | |
| echo "${result}" |