Skip to content

fix: resolve five latent bugs in util and actor modules#2056

Draft
farmdawgnation wants to merge 2 commits into
mainfrom
msf/puzzled-turner
Draft

fix: resolve five latent bugs in util and actor modules#2056
farmdawgnation wants to merge 2 commits into
mainfrom
msf/puzzled-turner

Conversation

@farmdawgnation
Copy link
Copy Markdown
Member

Summary

Gets the full test suite green on both Scala 2.13.18 and Scala 3.3.7 for all Lift modules. The baseline showed all real code already passing; the only failures were latent-bug regression specs (failing by design on 2.13, and not even compiling on Scala 3). This fixes the five underlying bugs and repairs the specs.

Bugs fixed

  • SecurityHelpers.randomLong / randomIntmath.abs(value) % mod overflows for MinValue (stays negative), so results could be negative. Now reduces via math.floorMod through a new nonNegativeMod helper.
  • CurrencyZone.getreplaceAll treated the grouping separator as a regex (German . erased every digit, then round threw NumberFormatException). Now strips the grouping separator literally, normalizes the decimal separator to ., and drops residual non-numeric characters (German currency NBSP).
  • TimeHelpers TimeSpan.format — week scale divisor of 10000 wrapped weeks at the 10000 boundary. Changed to Long.MaxValue so the largest unit never caps.
  • StringHelpers.splitNameValuePairs — reading pair(1) threw IndexOutOfBounds for entries with no =. Now pattern-matches and handles the missing-value case.
  • LAFuture.collect — over-allocated the accumulator (0 to len) and used insert (which shifts) instead of update, returning results in completion order rather than input order. Fixed to 0 until len + update.

Regression specs (LatentBugsSpec, LatentCollectBugSpec) now exercise the real APIs and use cross-version beEqualTo.

Test results

sbt test exits 0 on both versions:

Module 2.13.18 3.3.7
common 146 ✅ 146 ✅
actor 26 ✅ 26 ✅
markdown 12 ✅ 12 ✅
util 507 ✅ 507 ✅
webkit 282 ✅ 282 ✅
testkit

🤖 Generated with Claude Code

farmdawgnation and others added 2 commits May 31, 2026 15:11
Baseline tests passed for all real code on Scala 2.13.18 and 3.3.7; the
only failures were latent-bug regression specs. Fix the underlying bugs
and repair the specs so the full suite is green on both Scala versions.

- SecurityHelpers.randomLong/randomInt: math.abs(MinValue) overflows and
  stays negative, so the modulo could be negative. Reduce via math.floorMod
  through a new nonNegativeMod helper.
- CurrencyZone.get: replaceAll treated the grouping separator as a regex
  (German '.' erased every digit). Strip it literally, normalise the
  decimal separator to '.', and drop residual non-numeric characters so
  round()'s BigDecimal parse no longer throws for EU locales.
- TimeHelpers TimeSpan.format: week scale divisor of 10000 wrapped weeks;
  use Long.MaxValue so the largest unit never caps.
- StringHelpers.splitNameValuePairs: reading pair(1) threw
  IndexOutOfBounds for entries with no '='; pattern-match and handle the
  missing-value case.
- LAFuture.collect: over-allocated the accumulator (0 to len) and used
  insert (which shifts) instead of update, returning results in completion
  order. Use 0 until len + update to preserve input order.

Specs exercise the real APIs and use cross-version beEqualTo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes latent utility and actor bugs in Lift and adds regression specs intended to keep behavior green across Scala 2.13 and Scala 3.

Changes:

  • Fixes modulo handling, currency normalization, time-span formatting, string pair parsing, and LAFuture collection ordering.
  • Adds shared regression specs for the utility bugs and actor collection ordering.
  • Updates LAFuture.collect/collectAll to write results by input index.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
core/util/src/main/scala/net/liftweb/util/SecurityHelpers.scala Replaces math.abs(...) % mod with floorMod-based reduction.
core/util/src/main/scala/net/liftweb/util/CurrencyZone.scala Normalizes locale-specific formatted currency strings into BigDecimal-compatible strings.
core/util/src/main/scala/net/liftweb/util/TimeHelpers.scala Removes the artificial 10000-week cap in TimeSpan.format.
core/util/src/main/scala/net/liftweb/util/StringHelpers.scala Handles name/value entries missing an explicit value.
core/actor/src/main/scala/net/liftweb/actor/LAFuture.scala Preserves input ordering when collecting future results.
core/util/src/test/scala/net/liftweb/util/LatentBugsSpec.scala Adds regression coverage for utility latent bugs.
core/actor/src/test/scala/net/liftweb/actor/LatentCollectBugSpec.scala Adds regression coverage for out-of-order future completion.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +55 to +60
val list = props.split(",").toList.flatMap(in => {
in.roboSplit("=") match {
case name :: value :: _ => Some((name, unquote(value)))
case name :: Nil if name.nonEmpty => Some((name, ""))
case _ => None
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants