CGI-Lingua

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

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 )