disarm 0.14.1-aarch64-linux → 0.16.0-aarch64-linux
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 +4 -4
- data/README.md +5 -4
- data/lib/disarm/3.1/disarm.so +0 -0
- data/lib/disarm/3.2/disarm.so +0 -0
- data/lib/disarm/3.3/disarm.so +0 -0
- data/lib/disarm/3.4/disarm.so +0 -0
- data/lib/disarm/4.0/disarm.so +0 -0
- data/lib/disarm/version.rb +1 -1
- data/lib/disarm.rb +169 -23
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8ecc331ffb977947b213f31133c21afa3aede8d64f44a43a5e624eeb122013df
|
|
4
|
+
data.tar.gz: e09891674097fa1eb7f61318e3df6c7e23740a132e313f309012ff68a2951bfe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1784010e8ff92e9493d600eabb0bd856d56405310dd3d12b53fdc1badeddbb7c668efcf608812360f2332772c51735cb7d44dff5bf4d1287dc5ec74497ac1bd3
|
|
7
|
+
data.tar.gz: 0dfc2d60de872b386ac671594a8bea2bc0c4cf87b731c15343dc488d494c4d9e8a7bc4728b7249a44877b2d82ec953ea3c3135299f8ef973f458a1302f40b7ba
|
data/README.md
CHANGED
|
@@ -19,9 +19,10 @@ gem "disarm"
|
|
|
19
19
|
gem install disarm
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Requires Ruby >= 3.1.
|
|
23
|
-
(Linux x86_64/aarch64, macOS x86_64/arm64, Windows)
|
|
24
|
-
|
|
22
|
+
Requires Ruby >= 3.1. Precompiled platform gems ship for Ruby 3.1 through 4.0
|
|
23
|
+
(Linux x86_64/aarch64, macOS x86_64/arm64, Windows). On a supported Ruby with no
|
|
24
|
+
matching platform gem, the source gem installs and compiles locally, which needs a
|
|
25
|
+
Rust toolchain. Below 3.1 the gem does not install at all.
|
|
25
26
|
|
|
26
27
|
## Usage
|
|
27
28
|
|
|
@@ -49,7 +50,7 @@ Disarm.demojize("I ❤️ Ruby") # => "I red heart Ruby
|
|
|
49
50
|
Disarm.demojize("👍🏽", strip_modifiers: true)
|
|
50
51
|
|
|
51
52
|
# Security presets
|
|
52
|
-
Disarm.strip_obfuscation("Ѕ𝗲𝗰𝗿𝗲𝘁
|
|
53
|
+
Disarm.strip_obfuscation("Ѕ𝗲𝗰𝗿𝗲𝘁 \u200bdata") # deobfuscated
|
|
53
54
|
Disarm.canonicalize("…") # homoglyph/bidi/zero-width clean
|
|
54
55
|
|
|
55
56
|
# IDN / hostname spoof check (a false result is not a safety guarantee)
|
data/lib/disarm/3.1/disarm.so
CHANGED
|
Binary file
|
data/lib/disarm/3.2/disarm.so
CHANGED
|
Binary file
|
data/lib/disarm/3.3/disarm.so
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/disarm/version.rb
CHANGED
data/lib/disarm.rb
CHANGED
|
@@ -55,15 +55,22 @@ module Disarm
|
|
|
55
55
|
|
|
56
56
|
# Fold cross-script confusables toward `target:` (:latin or :cyrillic).
|
|
57
57
|
#
|
|
58
|
-
# `digit_policy:` selects how non-Latin DIGITS fold (#561).
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
58
|
+
# `digit_policy:` selects how non-Latin DIGITS fold (#561).
|
|
59
|
+
#
|
|
60
|
+
# `:numeric` (default) sends them to the ASCII digit — `०` becomes `0` — which is
|
|
61
|
+
# right for prose, where a Devanagari zero really is a zero.
|
|
62
|
+
#
|
|
63
|
+
# `:tr39` uses upstream's targets, which send most of them to a Latin letter
|
|
64
|
+
# (`०` → `o`; three of the 45 rows fold to `.` or to the two characters `rn`
|
|
65
|
+
# instead). That is what an identifier *skeleton* wants, since its only job is to
|
|
66
|
+
# make two confusable identifiers collide. The two differ on 45 rows and agree
|
|
67
|
+
# everywhere else. Scoped to `target: :latin` — the override rows are generated from
|
|
68
|
+
# the Latin table and carry TR39's Latin-script targets, so with `target: :cyrillic`
|
|
69
|
+
# it is a no-op.
|
|
70
|
+
#
|
|
71
|
+
# `:preserve` leaves the digit alone (#648). The other two both yield a mixed-script
|
|
72
|
+
# numeral — `२०२४` becomes `२0२४` or `२o२४` — so neither keeps the script. Unlike
|
|
73
|
+
# `:tr39` it applies under every target script.
|
|
67
74
|
def normalize_confusables(text, target: :latin, digit_policy: :numeric)
|
|
68
75
|
translate_errors { _normalize_confusables(text, target.to_s, digit_policy.to_s) }
|
|
69
76
|
end
|
|
@@ -109,18 +116,58 @@ module Disarm
|
|
|
109
116
|
translate_errors { _demojize(text, strip_modifiers) }
|
|
110
117
|
end
|
|
111
118
|
|
|
119
|
+
# Replace every emoji with +replacement+, verbatim.
|
|
120
|
+
#
|
|
121
|
+
# The counterpart to +demojize+, and a different question of a different table.
|
|
122
|
+
# +demojize+ asks what CLDR calls a character, so its domain is the name table, which
|
|
123
|
+
# is wider than the emoji: <tt>demojize("x\u2122y")</tt> is "x trade mark y". This
|
|
124
|
+
# asks whether the UCD calls it an emoji — Emoji_Presentation=Yes, an Emoji=Yes base
|
|
125
|
+
# carrying U+FE0F, and the ZWJ, modifier, keycap and flag sequences on those. Nothing
|
|
126
|
+
# else moves.
|
|
127
|
+
#
|
|
128
|
+
# +replacement+ is inserted exactly as given: "" closes an intra-word split and " "
|
|
129
|
+
# keeps two words apart, and no rule serves both.
|
|
130
|
+
def replace_emoji(text, replacement = "")
|
|
131
|
+
translate_errors { _replace_emoji(text, replacement) }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Canonicalize, but raise rather than silently normalize a structural difference
|
|
135
|
+
# away — the half of the pair that lets a caller reject input instead of comparing
|
|
136
|
+
# a value the sender never wrote.
|
|
137
|
+
def canonicalize_strict(text, digit_policy: :numeric)
|
|
138
|
+
translate_errors { _canonicalize_strict(text, digit_policy.to_s) }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Strip the non-interchange and invisible classes while KEEPING the script.
|
|
142
|
+
#
|
|
143
|
+
# Unlike `canonicalize` it folds no confusables, so non-Latin text survives as
|
|
144
|
+
# itself. It cannot be rebuilt from the seven universal `strip_*` methods, and the
|
|
145
|
+
# difference runs both ways: this preserves the Private Use Area (icon fonts) and
|
|
146
|
+
# keeps the VS15/VS16 presentation selectors after a base, which the naive chain
|
|
147
|
+
# deletes, and it collapses TAB/LF to a space, which the primitives leave alone.
|
|
148
|
+
def strip_format(text)
|
|
149
|
+
_strip_format(text)
|
|
150
|
+
end
|
|
151
|
+
|
|
112
152
|
# Remove obfuscation (zero-width, bidi, combining-mark abuse) while keeping
|
|
113
153
|
# legible content.
|
|
114
|
-
def strip_obfuscation(text)
|
|
115
|
-
translate_errors { _strip_obfuscation(text) }
|
|
154
|
+
def strip_obfuscation(text, digit_policy: :numeric)
|
|
155
|
+
translate_errors { _strip_obfuscation(text, digit_policy.to_s) }
|
|
116
156
|
end
|
|
117
157
|
|
|
118
158
|
# Canonicalize text for security-sensitive comparison: strip obfuscation,
|
|
119
159
|
# control characters, and other spoofing vectors. The name describes the
|
|
120
160
|
# mechanism (Unicode canonicalization for matching), not a safety guarantee —
|
|
121
161
|
# this is not an output sanitizer; encode at the sink.
|
|
122
|
-
|
|
123
|
-
|
|
162
|
+
#
|
|
163
|
+
# Two steps introduce ASCII, not one (#719): the leading NFKC, and the confusable
|
|
164
|
+
# fold, which reaches characters NFKC leaves alone. U+2236 RATIO becomes ":", U+2044
|
|
165
|
+
# FRACTION SLASH becomes "/", U+2216 SET MINUS becomes "\\". A string that carried no
|
|
166
|
+
# delimiter can leave here carrying one. #inspect_anomalies reports it as :confusable
|
|
167
|
+
# WHEN the word also carries an ASCII letter, which is the gate that keeps ordinary
|
|
168
|
+
# non-Latin text from firing; a delimiter-only string is not reported.
|
|
169
|
+
def canonicalize(text, digit_policy: :numeric)
|
|
170
|
+
translate_errors { _canonicalize(text, digit_policy.to_s) }
|
|
124
171
|
end
|
|
125
172
|
|
|
126
173
|
# @deprecated Renamed to {#canonicalize} in 0.11 (the +_clean+ name
|
|
@@ -133,22 +180,60 @@ module Disarm
|
|
|
133
180
|
# Case/accent/script-insensitive search lookup key. `lang:` applies a
|
|
134
181
|
# language profile for transliteration (e.g. "ru", "uk"); nil means none.
|
|
135
182
|
# Raises Disarm::InvalidArgument on an unknown lang.
|
|
136
|
-
def search_key(text, lang: nil)
|
|
137
|
-
translate_errors { _search_key(text, lang&.to_s) }
|
|
183
|
+
def search_key(text, lang: nil, digit_policy: :numeric)
|
|
184
|
+
translate_errors { _search_key(text, lang&.to_s, digit_policy.to_s) }
|
|
138
185
|
end
|
|
139
186
|
|
|
140
187
|
# Collation sort key (like #search_key, but keeps base accented characters
|
|
141
188
|
# for correct ordering). `lang:` applies a language profile; nil means none.
|
|
142
189
|
# Raises Disarm::InvalidArgument on an unknown lang.
|
|
143
|
-
def sort_key(text, lang: nil)
|
|
144
|
-
translate_errors { _sort_key(text, lang&.to_s) }
|
|
190
|
+
def sort_key(text, lang: nil, digit_policy: :numeric)
|
|
191
|
+
translate_errors { _sort_key(text, lang&.to_s, digit_policy.to_s) }
|
|
145
192
|
end
|
|
146
193
|
|
|
147
194
|
# Library catalog deduplication key (search_key plus confusable folding).
|
|
148
195
|
# `lang:` applies a language profile; `strict_iso9:` selects the ISO 9:1995
|
|
149
196
|
# Cyrillic scheme. Raises Disarm::InvalidArgument on an unknown lang.
|
|
150
|
-
def catalog_key(text, lang: nil, strict_iso9: false)
|
|
151
|
-
translate_errors { _catalog_key(text, lang&.to_s, strict_iso9) }
|
|
197
|
+
def catalog_key(text, lang: nil, strict_iso9: false, digit_policy: :numeric)
|
|
198
|
+
translate_errors { _catalog_key(text, lang&.to_s, strict_iso9, digit_policy.to_s) }
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# The TR39 identifier skeleton plus the two prototype classes disarm keeps apart
|
|
202
|
+
# (#650). A spoof key: its only job is to make confusable identifiers collide, and its
|
|
203
|
+
# output is never for display. `digit_policy:` is `:numeric` (the letter half only),
|
|
204
|
+
# `:tr39` (adds `1 ≡ l` and `0 ≡ O`) or `:preserve` (a non-Latin numeral keeps its
|
|
205
|
+
# script).
|
|
206
|
+
def skeleton_key(text, digit_policy: :numeric)
|
|
207
|
+
translate_errors { _skeleton_key(text, digit_policy.to_s) }
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Levenshtein edit distance between `a` and `b`, in characters (#894). The one class
|
|
211
|
+
# of registry spoofing the confusable tables deliberately do not model — `paypa1`,
|
|
212
|
+
# `adm1n`. Canonicalize both sides first when composed and decomposed spellings
|
|
213
|
+
# should compare equal.
|
|
214
|
+
def edit_distance(left, right)
|
|
215
|
+
translate_errors { _edit_distance(left, right) }
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# The candidate closest to `value`, as `{ value:, distance: }`, or nil beyond
|
|
219
|
+
# `max_distance:` (#894). Reports; it does not decide. An exact match is reported with
|
|
220
|
+
# distance 0, and ties go to the first candidate at the lowest distance.
|
|
221
|
+
def nearest_match(value, candidates, max_distance: 1)
|
|
222
|
+
hit = translate_errors { _nearest_match(value, candidates.map(&:to_s), max_distance) }
|
|
223
|
+
hit && { value: hit[0], distance: hit[1] }
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Whether `text` is already its own canonical form under `preset:` (#730).
|
|
227
|
+
#
|
|
228
|
+
# The verification-path counterpart to the presets: text in, normalized text out is
|
|
229
|
+
# the generation path, and this is the question a caller asks about bytes that arrive
|
|
230
|
+
# already bound. `has_anomalies?` is not this predicate — 142,760 assigned code points are
|
|
231
|
+
# reported clean by the detector and are not their own canonical form.
|
|
232
|
+
#
|
|
233
|
+
# `preset:` is any name in the preset registry or any profile. Raises
|
|
234
|
+
# Disarm::InvalidArgument on an unknown one.
|
|
235
|
+
def canonical?(text, preset: "canonicalize")
|
|
236
|
+
translate_errors { _is_canonical?(text, preset.to_s) }
|
|
152
237
|
end
|
|
153
238
|
|
|
154
239
|
# Strip diacritics ("café" → "cafe").
|
|
@@ -208,14 +293,14 @@ module Disarm
|
|
|
208
293
|
# confusable test flags essentially every non-Latin host), not a precise verdict;
|
|
209
294
|
# branch on the granular signals plus your own policy. Keys: :suspicious,
|
|
210
295
|
# :scripts, :mixed_script, :has_confusables, :bidi_conflict, :bidi_control,
|
|
211
|
-
# :has_invisible, :cross_label_script,
|
|
296
|
+
# :has_invisible, :compat_fold, :cross_label_script,
|
|
212
297
|
# :label_scripts, :whole_script_confusable, :label_whole_script_confusable,
|
|
213
298
|
# :canonical. `:whole_script_confusable` is a graded signal, NOT folded into
|
|
214
299
|
# `:suspicious` (see #545).
|
|
215
300
|
def analyze_hostname(host, contractions: false)
|
|
216
301
|
suspicious, scripts, mixed_script, has_confusables, bidi_conflict,
|
|
217
|
-
bidi_control, has_invisible, cross_label_script, label_scripts,
|
|
218
|
-
whole_script_confusable, label_whole_script_confusable, canonical =
|
|
302
|
+
bidi_control, has_invisible, compat_fold, cross_label_script, label_scripts,
|
|
303
|
+
whole_script_confusable, (label_whole_script_confusable, canonical) =
|
|
219
304
|
translate_errors { _analyze_hostname(host, contractions) }
|
|
220
305
|
{
|
|
221
306
|
suspicious:,
|
|
@@ -225,6 +310,7 @@ module Disarm
|
|
|
225
310
|
bidi_conflict:,
|
|
226
311
|
bidi_control:,
|
|
227
312
|
has_invisible:,
|
|
313
|
+
compat_fold:,
|
|
228
314
|
cross_label_script:,
|
|
229
315
|
label_scripts:,
|
|
230
316
|
whole_script_confusable:,
|
|
@@ -337,6 +423,12 @@ module Disarm
|
|
|
337
423
|
# (default), :windows, or :posix; `preserve_extension:` keeps the final
|
|
338
424
|
# extension when truncating to `max_length:`. Raises Disarm::InvalidArgument
|
|
339
425
|
# on an unknown platform.
|
|
426
|
+
#
|
|
427
|
+
# A safe *filename*, not a safe URL path segment. "%" is legal in a filename, so one
|
|
428
|
+
# the caller typed is kept — sanitize_filename("..%2Fetc") returns "%2Fetc" — and a
|
|
429
|
+
# consumer that percent-decodes the result must validate AFTER decoding. What this
|
|
430
|
+
# will not do is manufacture one: "%" never appears in the output unless it appeared
|
|
431
|
+
# in the input (#721).
|
|
340
432
|
def sanitize_filename(text, separator: "_", max_length: 255, platform: :universal,
|
|
341
433
|
lang: nil, preserve_extension: true)
|
|
342
434
|
translate_errors do
|
|
@@ -415,6 +507,15 @@ module Disarm
|
|
|
415
507
|
translate_errors { _has_bidi_conflict?(text) }
|
|
416
508
|
end
|
|
417
509
|
|
|
510
|
+
# Whether `text` carries any of the twelve UAX #9 explicit formatting characters,
|
|
511
|
+
# with no context taken into account. The counterpart to `bidi_conflict?`, which
|
|
512
|
+
# reads strong-direction letters and is blind to these; the two are disjoint. The
|
|
513
|
+
# anomaly detector's `bidi` kind reports nine of the twelve, holding back LRM, RLM
|
|
514
|
+
# and ALM because a lone directional mark is ordinary in right-to-left text.
|
|
515
|
+
def bidi_control?(text)
|
|
516
|
+
_has_bidi_control?(text)
|
|
517
|
+
end
|
|
518
|
+
|
|
418
519
|
# Explain how `lang: "auto"` detection resolves `text`: a hash with
|
|
419
520
|
# `:script`, `:chosen_lang` (both nil if undetected), `:reason`, and
|
|
420
521
|
# `:discriminators_hit`.
|
|
@@ -438,9 +539,39 @@ module Disarm
|
|
|
438
539
|
translate_errors { _script_info(name.to_s) }
|
|
439
540
|
end
|
|
440
541
|
|
|
542
|
+
# TR39 confusable sources whose prototype is in +script+, and how many of those
|
|
543
|
+
# disarm's bundled tables fold. Returns a Hash with +:script+, +:sources+ and
|
|
544
|
+
# +:folded+ keys.
|
|
545
|
+
#
|
|
546
|
+
# The denominator +unmapped_confusables+ does not have: that measures one bundled
|
|
547
|
+
# table against the whole 6,565-source population, so a script disarm ships no table
|
|
548
|
+
# for reports a number determined by that absence rather than by its coverage.
|
|
549
|
+
#
|
|
550
|
+
# +:folded+ counts sources any bundled table reaches, not sources folded *toward*
|
|
551
|
+
# this script — Greek is 71 of 159, because the Latin table folds Greek letters that
|
|
552
|
+
# look Latin. A script disarm knows that TR39 never uses as a prototype returns 0 of
|
|
553
|
+
# 0. Raises Disarm::InvalidArgument on an unknown script.
|
|
554
|
+
def confusable_coverage(script)
|
|
555
|
+
translate_errors { _confusable_coverage(script.to_s) }
|
|
556
|
+
end
|
|
557
|
+
|
|
441
558
|
# The Unicode `confusables.txt` release the bundled confusable tables were folded
|
|
442
559
|
# from, e.g. "17.0.0". Not a Unicode version for the library as a whole — the
|
|
443
560
|
# case-folding and width tables track different releases (see docs/provenance.md).
|
|
561
|
+
# The UCD release disarm's normalizer implements. Not a library-wide Unicode
|
|
562
|
+
# version — the bundled tables track different releases. This is the one integrators
|
|
563
|
+
# ask about: it decides whether disarm's normalization agrees with Ruby's.
|
|
564
|
+
def unicode_version
|
|
565
|
+
_unicode_version
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# Whether a key stored under an earlier release still compares equal. A monotonic
|
|
569
|
+
# counter, not a version: two artifacts reporting the same value produce the same key
|
|
570
|
+
# for the same input. Meaningless in isolation, by design.
|
|
571
|
+
def key_schema_version
|
|
572
|
+
_key_schema_version
|
|
573
|
+
end
|
|
574
|
+
|
|
444
575
|
def confusables_version
|
|
445
576
|
translate_errors { _confusables_version }
|
|
446
577
|
end
|
|
@@ -512,7 +643,9 @@ module Disarm
|
|
|
512
643
|
# pipe.process("Café") # => "cafe"
|
|
513
644
|
# pipe.process("Köln") # reuse the same handle
|
|
514
645
|
#
|
|
515
|
-
# Disarm::Pipeline#process is the Rust-defined instance method on the handle
|
|
646
|
+
# Disarm::Pipeline#process is the Rust-defined instance method on the handle, and
|
|
647
|
+
# Disarm::Pipeline#with_digit_policy(policy) returns a copy whose confusable passes
|
|
648
|
+
# fold under `policy` (#646); a profile with no confusables step refuses one.
|
|
516
649
|
def get_pipeline(profile)
|
|
517
650
|
translate_errors { _get_pipeline(profile.to_s) }
|
|
518
651
|
end
|
|
@@ -553,4 +686,17 @@ module Disarm
|
|
|
553
686
|
raise Error, e.message, e.backtrace
|
|
554
687
|
end
|
|
555
688
|
end
|
|
689
|
+
|
|
690
|
+
# The reusable handle `Disarm.get_pipeline` returns. `#process` is Rust-defined; this
|
|
691
|
+
# reopens the class for the one method that can fail, so its error arrives as
|
|
692
|
+
# `Disarm::InvalidArgument` the way every module-level call's does.
|
|
693
|
+
class Pipeline
|
|
694
|
+
# A copy of this pipeline whose confusable passes fold under `policy` (#646):
|
|
695
|
+
# `:numeric`, `:tr39` or `:preserve`. Raises Disarm::InvalidArgument when the profile
|
|
696
|
+
# has no confusables step and the policy is not the default — a setting that would
|
|
697
|
+
# never run is refused rather than kept.
|
|
698
|
+
def with_digit_policy(policy)
|
|
699
|
+
Disarm.send(:translate_errors) { _with_digit_policy(policy.to_s) }
|
|
700
|
+
end
|
|
701
|
+
end
|
|
556
702
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: disarm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Richard Quinn
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -98,6 +98,8 @@ files:
|
|
|
98
98
|
- lib/disarm/3.1/disarm.so
|
|
99
99
|
- lib/disarm/3.2/disarm.so
|
|
100
100
|
- lib/disarm/3.3/disarm.so
|
|
101
|
+
- lib/disarm/3.4/disarm.so
|
|
102
|
+
- lib/disarm/4.0/disarm.so
|
|
101
103
|
- lib/disarm/version.rb
|
|
102
104
|
homepage: https://github.com/raeq/disarm
|
|
103
105
|
licenses:
|
|
@@ -118,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
118
120
|
version: '3.1'
|
|
119
121
|
- - "<"
|
|
120
122
|
- !ruby/object:Gem::Version
|
|
121
|
-
version:
|
|
123
|
+
version: 4.1.dev
|
|
122
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
125
|
requirements:
|
|
124
126
|
- - ">="
|