Module: Saro::Dat::Util

Defined in:
lib/saro/dat/util.rb

Constant Summary collapse

U64_MAX =
0xFFFFFFFFFFFFFFFF

Class Method Summary collapse

Class Method Details

.decode_base64_url(s) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/saro/dat/util.rb', line 56

def decode_base64_url(s)
  return "".b if s.nil?
  if s.is_a?(String)
    return "".b if s.empty?
  end
  
  # Base64.decode64 is RFC 2045 and silently drops invalid characters, so
  # "!!!!invalid@@@@" would decode to arbitrary bytes instead of raising.
  # urlsafe_decode64 is strict, matching rust's decoder.
  s = s.to_s
  rem = s.bytesize % 4
  s += ("=" * (4 - rem)) if rem > 0

  begin
    Base64.urlsafe_decode64(s).b
  rescue ArgumentError => e
    raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CONFIG_ARGUMENT_INVALID, "not a valid base64url string", cause: e)
  end
end

.decode_base64_url_str(s) ⇒ Object



76
77
78
# File 'lib/saro/dat/util.rb', line 76

def decode_base64_url_str(s)
  decode_base64_url(s).force_encoding('utf-8')
end

.encode_base64_url(s) ⇒ Object



42
43
44
45
46
47
48
49
50
# File 'lib/saro/dat/util.rb', line 42

def encode_base64_url(s)
  return "".b if s.nil?
  if s.is_a?(String)
    return "".b if s.empty?
    enc = s.encoding
    s = s.encode('utf-8') unless enc == Encoding::BINARY || enc == Encoding::UTF_8
  end
  Base64.urlsafe_encode64(s, padding: false).b
end

.encode_base64_url_str(s) ⇒ Object



52
53
54
# File 'lib/saro/dat/util.rb', line 52

def encode_base64_url_str(s)
  encode_base64_url(s).force_encoding('ascii')
end

.parse_u64(s) ⇒ Object

Strict unsigned 64-bit decimal parse, matching rust's parse::<u64>(). Ruby's String#to_i never raises and Integer() accepts 0x, _ and surrounding whitespace, so the character set is checked explicitly. 무엇을 파싱하다 실패했는지에 따라 코드가 갈린다(토큰이면 TOKEN_MALFORMED, 인증서면 CERT_MALFORMED). 여기서는 중립적인 인자 오류로 두고, 각 호출부에서 정확한 코드로 감싼다.



19
20
21
22
23
24
25
26
27
28
# File 'lib/saro/dat/util.rb', line 19

def parse_u64(s)
  unless s.is_a?(String) && s.match?(/\A[0-9]+\z/)
    raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CONFIG_ARGUMENT_INVALID, "not an unsigned decimal integer: #{s.inspect}")
  end
  v = s.to_i
  if v > U64_MAX
    raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CONFIG_ARGUMENT_INVALID, "exceeds u64: #{s.inspect}")
  end
  v
end

.parse_u64_hex(s) ⇒ Object

Strict unsigned 64-bit hex parse, matching rust's u64::from_str_radix(s, 16).



31
32
33
34
35
36
37
38
39
40
# File 'lib/saro/dat/util.rb', line 31

def parse_u64_hex(s)
  unless s.is_a?(String) && s.match?(/\A[0-9a-fA-F]+\z/)
    raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CONFIG_ARGUMENT_INVALID, "not an unsigned hex integer: #{s.inspect}")
  end
  v = s.to_i(16)
  if v > U64_MAX
    raise Saro::Dat::Error.new(Saro::Dat::ErrorCode::CONFIG_ARGUMENT_INVALID, "exceeds u64: #{s.inspect}")
  end
  v
end