|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Announcing Scala.js 1.10.0 |
| 4 | +category: news |
| 5 | +tags: [releases] |
| 6 | +permalink: /news/2022/04/04/announcing-scalajs-1.10.0/ |
| 7 | +--- |
| 8 | + |
| 9 | + |
| 10 | +We are pleased to announce the release of Scala.js 1.10.0! |
| 11 | + |
| 12 | +**This release addresses a security vulnerability in `java.util.UUID.randomUUID()`.** |
| 13 | +All versions of Scala.js prior to 1.10.0 are affected, including all 0.6.x versions. |
| 14 | +We strongly recommend that all users upgrade to Scala.js 1.10.0 as soon as possible. |
| 15 | +Read [the security advisory](https://github.com/scala-js/scala-js/security/advisories/GHSA-j2f9-w8wh-9ww4) for more details. |
| 16 | +The issue was registered as [CVE-2022-28355](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-28355). |
| 17 | + |
| 18 | +This release also brings a new mode of module splitting, which creates the smallest possible modules for a given list of packages, and the fewest possible modules for the rest. |
| 19 | + |
| 20 | +Finally, it contains some minor optimizations, notably contributed by [@japgolly](https://github.com/japgolly). |
| 21 | + |
| 22 | +Read on for more details. |
| 23 | + |
| 24 | +<!--more--> |
| 25 | + |
| 26 | +## Getting started |
| 27 | + |
| 28 | +If you are new to Scala.js, head over to [the tutorial]({{ BASE_PATH }}/tutorial/). |
| 29 | + |
| 30 | +If you need help with anything related to Scala.js, you may find our community [in `#scala-js` on Discord](https://discord.com/invite/scala) and [on Stack Overflow](https://stackoverflow.com/questions/tagged/scala.js). |
| 31 | + |
| 32 | +Bug reports can be filed [on GitHub](https://github.com/scala-js/scala-js/issues). |
| 33 | + |
| 34 | +## Release notes |
| 35 | + |
| 36 | +If upgrading from Scala.js 0.6.x, make sure to read [the release notes of Scala.js 1.0.0]({{ BASE_PATH }}/news/2020/02/25/announcing-scalajs-1.0.0/) first, as they contain a host of important information, including breaking changes. |
| 37 | + |
| 38 | +This is a **minor** release: |
| 39 | + |
| 40 | +* It is backward binary compatible with all earlier versions in the 1.x series: libraries compiled with 1.0.x through 1.9.x can be used with 1.10.0 without change. |
| 41 | +* Despite being a minor release, 1.10.0 is forward binary compatible with 1.8.x and 1.9.x. It is *not* forward binary compatible with 1.7.x. Libraries compiled with 1.10.0 can be used with 1.8.x and 1.9.x but not with 1.7.x or earlier. |
| 42 | +* It is *not* entirely backward source compatible: it is not guaranteed that a codebase will compile *as is* when upgrading from 1.9.x (in particular in the presence of `-Xfatal-warnings`). |
| 43 | + |
| 44 | +As a reminder, libraries compiled with 0.6.x cannot be used with Scala.js 1.x; they must be republished with 1.x first. |
| 45 | + |
| 46 | +## Fixes with compatibility concerns |
| 47 | + |
| 48 | +### `java.util.UUID.randomUUID()` now depends on `java.security.SecureRandom`, which is provided by external libraries |
| 49 | + |
| 50 | +Until Scala.js 1.9.x, `java.util.UUID.randomUUID()` was implemented using `java.util.Random`, which is not cryptographically secure. |
| 51 | +This is therefore a security issue concerning `randomUUID()`. |
| 52 | +To address that, Scala.js 1.10.x uses `java.security.SecureRandom` in the implementation of the latter instead. |
| 53 | +`java.util.Random` remains unchanged, since it correctly implements its (deterministic) specification. |
| 54 | + |
| 55 | +However, `SecureRandom` cannot be implemented on all JavaScript environments, as ECMAScript, per se, lacks any primitive to access a good source of entropy. |
| 56 | +While it can be implemented on top of browser APIs or Node.js APIs, we have no decent fallback for other cases. |
| 57 | +Not fully implementing it correctly for all platforms would go against our policy for the standard library, i.e., that linking code must be correct. |
| 58 | +Therefore, Scala.js core does not provide any implementation of `java.security.SecureRandom`. |
| 59 | + |
| 60 | +This means that code that was previously calling `java.util.UUID.randomUUID()` will now fail to link. |
| 61 | +To preserve binary compatibility, we introduce two variants of a library that provides `java.security.SecureRandom`: |
| 62 | + |
| 63 | +* [`scalajs-java-securerandom`](https://github.com/scala-js/scala-js-java-securerandom) provides a *correct*, cryptographically secure implementation of `java.security.SecureRandom`, but relies on the Node.js `crypto` module or the Web Crypto API `crypto.getRandomValues` to be available (e.g., in browsers). |
| 64 | +* [`scalajs-fake-insecure-securerandom`](https://github.com/scala-js/scala-js-fake-insecure-securerandom) is a fake, *insecure* implementation that works in any ECMAScript environment. The only reason this exists is to unblock migration from Scala.js 1.9.x and earlier, in situations that require `randomUUID()` and can accept that they will be insecure. |
| 65 | + |
| 66 | +Due to the changes in the core library, you may encounter linking errors when upgrading to Scala.js 1.10.0, such as: |
| 67 | + |
| 68 | +{% highlight text %} |
| 69 | +[error] Referring to non-existent class java.security.SecureRandom |
| 70 | +[error] called from private java.util.UUID$.csprng$lzycompute()java.util.Random |
| 71 | +[error] called from private java.util.UUID$.csprng()java.util.Random |
| 72 | +[error] called from java.util.UUID$.randomUUID()java.util.UUID |
| 73 | +[error] called from static java.util.UUID.randomUUID()java.util.UUID |
| 74 | +[error] called from helloworld.HelloWorld$.main([java.lang.String)void |
| 75 | +[error] called from static helloworld.HelloWorld.main([java.lang.String)void |
| 76 | +[error] called from core module module initializers |
| 77 | +[error] involving instantiated classes: |
| 78 | +[error] java.util.UUID$ |
| 79 | +[error] helloworld.HelloWorld$ |
| 80 | +{% endhighlight %} |
| 81 | + |
| 82 | +You may fix these linking errors by adding the following dependency to your `libraryDependencies`: |
| 83 | + |
| 84 | +{% highlight scala %} |
| 85 | +"org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0" |
| 86 | +{% endhighlight %} |
| 87 | + |
| 88 | +As mentioned above, this will only work in environments that either provide the Web Crypto API, or Node.js' `crypto` module. |
| 89 | + |
| 90 | +If you need random UUID generation in other environments, we encourage you to implement it yourselves. |
| 91 | +Find out if your environment provides a source of cryptographically secure pseudo-random numbers. |
| 92 | +If it does, you may want to use it to shim `crypto.getRandomValues`, and/or send a pull request to [`scalajs-java-securerandom`](https://github.com/scala-js/scala-js-java-securerandom). |
| 93 | +Otherwise, replace calls to `randomUUID()` with another implementation, in a way that corresponds to your requirements in terms of security and collision likelihood. |
| 94 | + |
| 95 | +If you have **no other choice**, depend on `scalajs-fake-insecure-securerandom` instead. |
| 96 | +As its name implies, this is an *insecure* implementation, and you should get rid of this dependency as soon as possible. |
| 97 | + |
| 98 | +## New module split style: `SmallModulesFor(packages)` |
| 99 | + |
| 100 | +Prior to 1.10.0, Scala.js had two opposite module split styles: |
| 101 | + |
| 102 | +* `FewestModules` (the default), which generates as few modules as possible, and |
| 103 | +* `SmallestModules`, which generates as many small modules as possible (up to one per class). |
| 104 | + |
| 105 | +As detailed in [#4327](https://github.com/scala-js/scala-js/issues/4327), those two extremes both suffered from issues for iterative development. |
| 106 | + |
| 107 | +Scala.js 1.10.0 introduces a third style, `ModuleSplitStyle.SmallModulesFor(packages: List[String])`. |
| 108 | +That style creates as many small modules as possibles for the classes in the listed packages (and their subpackages). |
| 109 | +For all other classes, it generates as few modules as possible. |
| 110 | +It is a combination of the previously existing styles. |
| 111 | + |
| 112 | +The typical usage pattern is to list the application's packages as argument. |
| 113 | +This way, often-changing classes receive independent, small modules, while the stable classes coming from libraries are bundled together as much as possible. |
| 114 | +For example, if your application code lives in `com.example.myapp`, you could configure your module split style as: |
| 115 | + |
| 116 | +{% highlight scala %} |
| 117 | +import org.scalajs.linker.interface.ModuleSplitStyle |
| 118 | +scalaJSLinkerConfig ~= (_.withModuleSplitStyle(ModuleSplitStyle.SmallModulesFor(List("com.example.myapp")))) |
| 119 | +{% endhighlight %} |
| 120 | + |
| 121 | +## Miscellaneous |
| 122 | + |
| 123 | +### Optimizations |
| 124 | + |
| 125 | +Scala.js 1.10.0 brings some new optimizations to the produced JavaScript files: |
| 126 | + |
| 127 | +* Closures that do not need to capture anything produce simple lambdas, instead of redundant IIFEs (Immediately Invoked Function Expressions); contributed by [@japgolly](https://github.com/japgolly) |
| 128 | +* `js.dynamicImport` blocks that do nothing but access a native JS class, object or member from a JS module avoid creating an intermediate Scala.js-generated module; instead they directly refer to the target JS module in the generated dynamic `import()` call. |
| 129 | + |
| 130 | +## Bug fixes |
| 131 | + |
| 132 | +Among others, the following bugs have been fixed in 1.10.0: |
| 133 | + |
| 134 | +* [#4657](https://github.com/scala-js/scala-js/issues/4657) Scala.js should not provide a cryptographically insecure `UUID.randomUUID()` implementation |
| 135 | + |
| 136 | +You can find the full list [on GitHub](https://github.com/scala-js/scala-js/issues?q=is%3Aissue+milestone%3Av1.10.0+is%3Aclosed). |
0 commit comments