CGI-Lingua
view release on metacpan or search on metacpan
Revision history for CGI-Lingua
0.85 Thu Aug 27 11:35:33 AM EDT 2026
[ Bug Fixes ]
- Data::Validate::IP and NetAddr::IP moved from required to recommended;
NetAddr::IP::UtilPP fails to build on Windows (mask4to6 bad-argument error),
which cascades to Data::Validate::IP, crashing country() on import; a
package-level $_have_dvip sentinel tries to load Data::Validate::IP once and,
on failure, installs pure-Perl fallbacks (using Socket::inet_pton for IPv6
validation) as aliases for is_ipv4(), is_ipv6(), is_private_ip(), and
is_loopback_ip() so the rest of country() is unchanged on both platforms
- _code2countryname(): when Locale::Object's database is absent, fall back to
Locale::Codes::Country::code2country() via the new _country_short_name()
helper; a %COUNTRY_SHORT_NAMES table overrides the ~15 codes where
Locale::Codes returns the full ISO official name (e.g. "United Kingdom of
Great Britain and Northern Ireland") instead of the common short form
("United Kingdom") â fixes sublanguage() returning 'Unknown' for en-gb and
en-us on Windows CI where Locale::Object's SQLite database is not installed
- Locale::Object::Country->new() and Locale::Object::DB->new() now wrapped in
eval at every call site; a package-level $_locale_object_db_ok sentinel
(undef=unchecked, 0=absent, 1=present) prevents repeated failed attempts on
systems where Locale::Object's SQLite database is missing â common on Windows
CI runners where the .db file is not installed alongside the module; the
module now degrades gracefully (sublanguage/country name returns 'Unknown'
rather than dying) instead of propagating the "database was not in" exception
- Make Net::Subnet an optional (recommended) dependency rather than required;
Net::Subnet depends on Socket6 which requires C compilation and fails to
build on Windows; add a pure-Perl fallback (_in_baidu_subnet) for the single
185.10.104.0/22 check in _handle_eu_country so the module continues to
detect Baidu crawler IPs even when Net::Subnet is absent
- _resolve_sublanguage_match(): second path (I18N::AcceptLanguage returns a
full tag such as en-gb) now falls back to _country_short_name() before
setting sublanguage to 'Unknown', fixing sublanguage() returning 'Unknown'
for en-gb / en-us on Windows CI where Locale::Object's SQLite database is
not installed
- time_zone(): DateTime::TimeZone::Local->TimeZone() wrapped in eval with
local $SIG{__DIE__} so time_zone() returns undef gracefully on Windows
Perl builds that install the module but omit the TimeZone() method
[ Test Suite ]
- t/mutant_killers.t: three subtests that call ->name() on a Locale::Object
result now probe the Locale::Object database first and SKIP if absent,
preventing a "Can't call method 'name' on an undefined value" crash on
Windows CI runners
0.84 Thu Jul 30 03:07:22 PM EDT 2026
[ Security ]
- country(): after extracting the IPv4 portion of an ::ffff: mapped address,
validate it with is_ipv4() before proceeding to geo lookups; the untainting
regex uses \d{1,3} which matches 0-999, so ::ffff:999.999.999.999 previously
reached IP::Country with a nominally out-of-range address; on systems where
inet_aton wraps octets modulo 256, this silently became 231.231.231.231 (a
real routable IP) and returned a spurious country code
[ Bug Fixes ]
- new(): add local $SIG{__DIE__} inside the eval { JSON::PP::decode_json(...) }
guard so that applications using the Error module (or any other framework that
installs a $SIG{__DIE__} handler) do not see spurious "malformed JSON string"
log messages when the cache holds a legacy Storable blob; the eval already
discards the stale entry and falls through to fresh construction, but without
the local the handler intercepts the JSON parse exception before eval can
swallow it
- t/cgi_security.t: pre-require LWP::Simple::WithCache and JSON::Parse before
installing any Test::Mockingbird mocks; without this, the lazy
eval { require LWP::Simple::WithCache } inside country() loads the real
module on first call and clobbers the mock, causing the bogus-IP subtest
(::ffff:999.999.999.999) to make a real network call and receive a country
code instead of undef â matches the pre-require pattern already used in
( run in 0.678 second using v1.01-cache-2.11-cpan-e7c6538aa59 )