idnx 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e9eef708b35b383a3270b44ca3670e72d92bd3c29e89ecf2df9ba0ded94a144
4
- data.tar.gz: 4c08ebc4dc52aa8ccf6fe5b1c53c17e7eb2a6e07d11c7d689f049d757d6de379
3
+ metadata.gz: f0b5da39f881e947e1c29b5fbe5eb3647071e30316c817e6b87eeeba1c34af90
4
+ data.tar.gz: 3d5afd606ab46635d3db135952efae893963c460d87487302e83f3925b49143c
5
5
  SHA512:
6
- metadata.gz: 960e68d02443bf62b55290187f1785e16b9d16005107ce3b3f7db4ee016c1c91dd867de57d04f8cb92db18081a7b01499ac20fa8082f76ba884e8702806ff8ea
7
- data.tar.gz: 0be4f68aa311208b5652e2773192487cec450e6ff604d04a1d72f662136309928bd405a095f36eb4dc6f9180dafa10d1f90fe4f847225dd6288b5a2d4aeab29f
6
+ metadata.gz: a4c2583fc53027a4b37a6727f6ea0b40fe49ac84db9f1e35f687a79ff6924831e23d2bc259dc6fb86b0e6e89796fc05cf1a0b2901dbe9f8cfac02f7fb2a95bef
7
+ data.tar.gz: c28933fb3ae97ee2fe8c1eb9f80df6dff5fb66a063767db604f9ee7e9c49ff6ee5ac803f57c23488a6d3cc538f9d70c9bd5dabd9538df9a7a38545c5ddda33e8
data/CHANGELOG.md ADDED
@@ -0,0 +1,35 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.2] - 2026-11-11
4
+
5
+ * added missing license file.
6
+ * skip warnings when falling back to pure ruby version.
7
+ * remove pure ruby dead code for decoding.
8
+
9
+ ## [0.1.1] - 2021-10-03
10
+
11
+ Added missing RBS sig files to the gemspec.
12
+
13
+ ## [0.1.0] - 2021-09-04
14
+
15
+ ### improvements
16
+
17
+ It ships RBS signatures for the main public API.
18
+
19
+ ### compliance
20
+
21
+ `idnx` ships with a pure ruby punycode implementation (IDNA 2003), which will get loaded when `libidn2` isn't installed in the system. This was necessary for license compatibility, given that Apache 2.0 projects can rely on GPL dependencies (such as `libidn2`) but nnot exclusively.
22
+
23
+ ## [0.0.1] - 2021-06-11
24
+
25
+ This is the initial release.
26
+
27
+ ### Features
28
+
29
+ `idnx` ships with a single function, which translate Innternational domain names into Punycode names, which can be used for DNS requests:
30
+
31
+ ```ruby
32
+ require "idnx"
33
+
34
+ Idnx.to_punycode("bücher.de") #=> "xn--bcher-kva.de"
35
+ ```
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Idnx
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/idnx.svg)](http://rubygems.org/gems/idnx)
3
4
  [![CI](https://github.com/HoneyryderChuck/idnx/actions/workflows/test.yml/badge.svg)](https://github.com/HoneyryderChuck/idnx/actions/workflows/test.yml)
4
-
5
+ [![coverage report](https://honeyryderchuck.github.io/idnx/merged/badge_total.svg)](https://honeyryderchuck.github.io/idnx/merged/#_AllFiles)
5
6
 
6
7
 
7
8
  `idnx` provides a Ruby API for decoding Internationalized domain names into Punycode.
data/lib/idnx/idn2.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Idnx
4
- module Lib
4
+ module Idn2
5
5
  extend FFI::Library
6
6
 
7
7
  if FFI::Platform.mac?
@@ -55,4 +55,6 @@ module Idnx
55
55
  ascii
56
56
  end
57
57
  end
58
+
59
+ LIB = Idn2
58
60
  end
data/lib/idnx/ruby.rb CHANGED
@@ -8,7 +8,6 @@ module Idnx
8
8
  Punycode.encode_hostname(hostname)
9
9
  end
10
10
 
11
- # :nocov:
12
11
  # -*- coding: utf-8 -*-
13
12
  #--
14
13
  # punycode.rb - PunyCode encoder for the Domain Name library
@@ -78,12 +77,14 @@ module Idnx
78
77
  # Returns the numeric value of a basic code point (for use in
79
78
  # representing integers) in the range 0 to base-1, or nil if cp
80
79
  # is does not represent a value.
81
- DECODE_DIGIT = {}.tap do |map|
80
+ DECODE_DIGIT = begin
81
+ map = {} #: Hash[Integer, Integer]
82
82
  # ASCII A..Z map to 0..25
83
83
  # ASCII a..z map to 0..25
84
84
  (0..25).each { |i| map[65 + i] = map[97 + i] = i }
85
85
  # ASCII 0..9 map to 26..35
86
86
  (26..35).each { |i| map[22 + i] = i }
87
+ map
87
88
  end
88
89
 
89
90
  # Returns the basic code point whose value (when used for
@@ -109,7 +110,7 @@ module Idnx
109
110
 
110
111
  # Encode a +string+ in Punycode
111
112
  def encode(string)
112
- input = string.unpack("U*")
113
+ input = string.unpack("U*") #: Array[Integer]
113
114
  output = +""
114
115
 
115
116
  # Initialize the state
@@ -201,99 +202,6 @@ module Idnx
201
202
  end
202
203
  end.join(DOT)
203
204
  end
204
-
205
- # Decode a +string+ encoded in Punycode
206
- def decode(string)
207
- # Initialize the state
208
- n = INITIAL_N
209
- i = 0
210
- bias = INITIAL_BIAS
211
-
212
- if j = string.rindex(DELIMITER)
213
- b = string[0...j]
214
-
215
- b.match(RE_NONBASIC) &&
216
- raise(ArgumentError, "Illegal character is found in basic part: #{string.inspect}")
217
-
218
- # Handle the basic code points
219
-
220
- output = b.unpack("U*")
221
- u = string[(j + 1)..-1]
222
- else
223
- output = []
224
- u = string
225
- end
226
-
227
- # Main decoding loop: Start just after the last delimiter if any
228
- # basic code points were copied; start at the beginning
229
- # otherwise.
230
-
231
- input = u.unpack("C*")
232
- input_length = input.length
233
- h = 0
234
- out = output.length
235
-
236
- while h < input_length
237
- # Decode a generalized variable-length integer into delta,
238
- # which gets added to i. The overflow checking is easier
239
- # if we increase i as we go, then subtract off its starting
240
- # value at the end to obtain delta.
241
-
242
- oldi = i
243
- w = 1
244
- k = BASE
245
-
246
- loop do
247
- (digit = DECODE_DIGIT[input[h]]) ||
248
- raise(ArgumentError, "Illegal character is found in non-basic part: #{string.inspect}")
249
- h += 1
250
- i += digit * w
251
- raise BufferOverflowError if i > MAXINT
252
-
253
- t = k <= bias ? TMIN : k - bias >= TMAX ? TMAX : k - bias
254
- break if digit < t
255
-
256
- w *= BASE - t
257
- raise BufferOverflowError if w > MAXINT
258
-
259
- k += BASE
260
- (h < input_length) || raise(ArgumentError, "Malformed input given: #{string.inspect}")
261
- end
262
-
263
- # Adapt the bias
264
- delta = oldi == 0 ? i / DAMP : (i - oldi) >> 1
265
- delta += delta / (out + 1)
266
- bias = 0
267
- while delta > CUTOFF
268
- delta /= LOBASE
269
- bias += BASE
270
- end
271
- bias += (LOBASE + 1) * delta / (delta + SKEW)
272
-
273
- # i was supposed to wrap around from out+1 to 0, incrementing
274
- # n each time, so we'll fix that now:
275
-
276
- q, i = i.divmod(out + 1)
277
- n += q
278
- raise BufferOverflowError if n > MAXINT
279
-
280
- # Insert n at position i of the output:
281
-
282
- output[i, 0] = n
283
-
284
- out += 1
285
- i += 1
286
- end
287
- output.pack("U*")
288
- end
289
-
290
- # Decode a hostname using IDN/Punycode algorithms
291
- def decode_hostname(hostname)
292
- hostname.gsub(/(\A|#{Regexp.quote(DOT)})#{Regexp.quote(PREFIX)}([^#{Regexp.quote(DOT)}]*)/o) do
293
- Regexp.last_match(1) << decode(Regexp.last_match(2))
294
- end
295
- end
296
205
  end
297
- # :nocov:
298
206
  end
299
207
  end
data/lib/idnx/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Idnx
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/idnx/windows.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require "win32ole"
4
4
 
5
5
  module Idnx
6
- module Lib
6
+ module Windows
7
7
  extend FFI::Library
8
8
 
9
9
  ffi_lib "Normaliz.dll"
@@ -100,6 +100,9 @@ module Idnx
100
100
 
101
101
  unicode = utf8_ptr.read_string(utf8_ptr.size)
102
102
  unicode.strip! # remove null-byte
103
+ unicode
103
104
  end
104
105
  end
106
+
107
+ LIB = Windows
105
108
  end
data/lib/idnx.rb CHANGED
@@ -9,7 +9,7 @@ module Idnx
9
9
  module_function
10
10
 
11
11
  def to_punycode(hostname)
12
- Lib.lookup(hostname)
12
+ LIB.lookup(hostname)
13
13
  end
14
14
  end
15
15
 
@@ -21,6 +21,6 @@ else
21
21
  rescue LoadError
22
22
  # fallback to pure ruby punycode 2003 implementation
23
23
  require "idnx/ruby"
24
- Idnx::Lib = Idnx::Ruby
24
+ LIB = Idnx::Ruby
25
25
  end
26
26
  end
data/sig/idnx.rbs ADDED
@@ -0,0 +1,93 @@
1
+ module Idnx
2
+ VERSION: String
3
+
4
+ class Error < StandardError
5
+ end
6
+
7
+ module Idn2
8
+ extend FFI::Library
9
+
10
+ VERSION: String
11
+ IDN2_OK: Integer
12
+ IDN2_NFC_INPUT: Integer
13
+ IDN2_TRANSITIONAL: Integer
14
+ IDN2_NONTRANSITIONAL: Integer
15
+
16
+ FLAGS: Integer
17
+
18
+ def self?.lookup: (String hostname) -> String
19
+
20
+ def self?.idn2_lookup_ul: (String hostname, FFI::Pointer?, Integer flags) -> Integer
21
+
22
+
23
+ def self?.idn2_strerror: (Integer code) -> String
24
+
25
+ def self?.idn2_free: (FFI::Pointer?) -> void
26
+
27
+ def self?.idn2_check_version: (FFI::Pointer?) -> void
28
+ end
29
+
30
+ module Windows
31
+ extend FFI::Library
32
+
33
+ IDN_MAX_LENGTH: Integer
34
+ MB_ERR_INVALID_CHARS: Integer
35
+
36
+ ERROR_INSUFFICIENT_BUFFER: Integer
37
+ ERROR_INVALID_FLAGS: Integer
38
+ ERROR_INVALID_NAME: Integer
39
+ ERROR_INVALID_PARAMETER: Integer
40
+ ERROR_NO_UNICODE_TRANSLATION: Integer
41
+
42
+ def self?.lookup: (String hostname) -> String
43
+
44
+ def self?.IdnToAscii: (Integer, FFI::Pointer?, Integer, FFI::Pointer?, Integer) -> Integer
45
+
46
+ def self?.MultiByteToWideChar: (Integer, Integer, String, Integer, FFI::Pointer?, Integer) -> Integer
47
+
48
+ def self?.WideCharToMultiByte: (Integer, Integer, FFI::Pointer?, Integer, FFI::Pointer?, Integer, FFI::Pointer?, FFI::Pointer?) -> Integer
49
+ end
50
+
51
+ module Ruby
52
+ def self?.lookup: (String hostname) -> String
53
+
54
+ module Punycode
55
+ BASE: Integer
56
+ TMIN: Integer
57
+ TMAX: Integer
58
+ SKEW: Integer
59
+ DAMP: Integer
60
+ INITIAL_BIAS: Integer
61
+ INITIAL_N: Integer
62
+ DELIMITER: String
63
+
64
+ MAXINT: Integer
65
+
66
+ LOBASE: Integer
67
+ CUTOFF: Integer
68
+
69
+ RE_NONBASIC: Regexp
70
+
71
+ DECODE_DIGIT: Hash[Integer, Integer]
72
+
73
+ ENCODE_DIGIT: ^(Integer d, bool flag) -> String
74
+
75
+ DOT: String
76
+ PREFIX: String
77
+
78
+ class ArgumentError < ::ArgumentError
79
+ end
80
+
81
+ class BufferOverflowError < ArgumentError
82
+ end
83
+
84
+ def self?.encode: (String string) -> String
85
+
86
+ def self?.encode_hostname: (String hostname) -> String
87
+ end
88
+ end
89
+
90
+ def self?.to_punycode: (String hostname) -> String
91
+
92
+ LIB: singleton(Idn2) | singleton(Windows) | singleton(Ruby)
93
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: idnx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - HoneyryderChuck
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-09-04 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: ffi
@@ -35,6 +34,7 @@ extra_rdoc_files:
35
34
  - LICENSE.txt
36
35
  - README.md
37
36
  files:
37
+ - CHANGELOG.md
38
38
  - LICENSE.txt
39
39
  - README.md
40
40
  - lib/idnx.rb
@@ -42,13 +42,15 @@ files:
42
42
  - lib/idnx/ruby.rb
43
43
  - lib/idnx/version.rb
44
44
  - lib/idnx/windows.rb
45
+ - sig/idnx.rbs
45
46
  homepage: https://github.com/honeyryderchuck/idnx
46
- licenses: []
47
+ licenses:
48
+ - Apache 2.0
47
49
  metadata:
48
50
  homepage_uri: https://github.com/honeyryderchuck/idnx
49
51
  source_code_uri: https://github.com/honeyryderchuck/idnx
50
52
  changelog_uri: https://github.com/honeyryderchuck/idnx/-/blob/master/CHANGELOG.md
51
- post_install_message:
53
+ rubygems_mfa_required: 'true'
52
54
  rdoc_options: []
53
55
  require_paths:
54
56
  - lib
@@ -63,8 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
65
  - !ruby/object:Gem::Version
64
66
  version: '0'
65
67
  requirements: []
66
- rubygems_version: 3.2.15
67
- signing_key:
68
+ rubygems_version: 4.0.20
68
69
  specification_version: 4
69
70
  summary: Converts International Domain Names into Punycode. It uses (via FFI) 'libidn2'
70
71
  for Mac and Linux; for Windows, it uses native APIs.