Summary
Every .wasm in the published npm package statically links
extension-functions.c
from the SQLite contrib page. That file carries no copyright notice and no license grant
of any kind, so the published binaries contain third-party code whose redistribution terms
are undetermined.
This is easy to miss: the file is not vendored in this repository. It is downloaded during the
build (Makefile lines 9–11 at cff99da), so source-level license scanning of the repo does
not reveal it. It only shows up when the published artifacts are inspected.
We hit this during a license audit of a downstream product that ships these .wasm files to
end users' browsers via @powersync/web.
Where it comes from
Makefile at cff99da (master):
9: EXTENSION_FUNCTIONS = extension-functions.c
10: EXTENSION_FUNCTIONS_URL = https://www.sqlite.org/contrib/download/extension-functions.c?get=25
11: EXTENSION_FUNCTIONS_SHA3 = ee39ddf5eaa21e1d0ebcbceeab42822dd0c4f82d8039ce173fd4814807faabfa
16: extension-functions.c \ # in CFILES
30: extension-functions.c \ # in MC_CFILES
It is in both CFILES and MC_CFILES, so it ends up in every build variant. The SHA3-256 of
the file we downloaded matches EXTENSION_FUNCTIONS_SHA3, so we are looking at the same bytes
the build uses.
What the file says about its license
Nothing. A case-insensitive search over the 52,188-byte source returns zero occurrences of
copyright, license, licence, public domain, permission, and warranty. The only
attribution is a bare author line, Liam Healy, followed by a change history. There is no
grant of rights and no statement placing it in the public domain.
The contrib page does not help either: the word "license"
does not appear on it, and the only entry that says anything about terms is a different one
(sqlite_fk.tgz: "public domain source code"). So the page's authors do state terms when they
have them, and for extension-functions.c they state none.
SQLite itself being public domain does not extend to contributed files: the core is explicitly
dedicated to the public domain, whereas this file says nothing at all.
What the published packages actually contain
extension-functions.c registers SQL functions that core SQLite does not provide
(strfilter, padc, padl, padr, leftstr, rightstr, proper, charindex,
replicate, reverse, difference, median, variance, lower_quartile,
upper_quartile, …). Their names survive in the .wasm data section, so presence can be
verified directly:
import io, re, tarfile, urllib.request
URL = "https://registry.npmjs.org/@journeyapps/wa-sqlite/-/wa-sqlite-2.0.3.tgz"
MARKERS = [b"strfilter", b"padc", b"lower_quartile", b"upper_quartile", b"proper", b"leftstr"]
with tarfile.open(fileobj=io.BytesIO(urllib.request.urlopen(URL).read())) as tf:
for m in tf.getmembers():
if m.name.endswith(".wasm"):
data = tf.extractfile(m).read()
hit = [k.decode() for k in MARKERS if re.search(rb"\b" + k + rb"\b", data)]
print(m.name.split("/")[-1], hit)
Results:
| package |
.wasm files |
contain the markers |
@journeyapps/wa-sqlite@2.0.3 |
8 |
8 |
@journeyapps/wa-sqlite@2.0.4 (latest) |
8 |
8 |
wa-sqlite@1.0.0 (rhashimoto) |
2 |
2 |
As a control, core-SQLite symbols such as julianday and substr are found in the same files,
confirming the search method works.
Why this matters for the LICENSE file
package/LICENSE in the published tarball is:
MIT License
Copyright (c) 2023 Roy T. Hashimoto
That correctly covers this project's own code, but the published .wasm files also contain
code authored by someone else, under no license. Consumers who comply with the MIT terms are
still left redistributing code they have no demonstrable permission to redistribute.
Is it actually used?
Not by PowerSync, as far as we can tell. We searched the published sources of
@powersync/web@2.2.0 (125 files) and @powersync/common@2.2.0 (150 files) for every function
name that only extension-functions.c provides and found no references. Our own application
does not use them either.
We understand other consumers of this package may rely on these functions, which is why we
are not asking for them to be removed from the default build.
What we are asking for
Please offer a build of the artifacts that does not include extension-functions.c, alongside
the existing ones. Existing consumers keep exactly what they have today; consumers with a
license-compliance requirement can opt in.
Two shapes would work for us, and we would defer to whichever fits your release process better:
- Additional
dist/ artifacts in the same package — e.g. dist/wa-sqlite-noext.*,
dist/mc-wa-sqlite-async-noext.* (naming is yours), built from a CFILES / MC_CFILES
list without extension-functions.c. No new version line, no new package. Downstream
consumers of @powersync/web would alias the fixed import paths in vfs.js to the
-noext files.
- A separate version line or dist-tag of
@journeyapps/wa-sqlite built without the file.
Downstream consumers would pin it via npm overrides (since @powersync/web depends on an
exact version).
The change to the sources is small as far as we can see (static inspection only, not yet
built): drop extension-functions.c from CFILES (line 16) and MC_CFILES (line 30), drop
"_RegisterExtensionFunctions" from src/exported_functions.json (line 2), and skip the
Module.ccall('RegisterExtensionFunctions', …) call in sqlite3.open_v2 (src/sqlite-api.js
line 526) for the variant. RegisterExtensionFunctions is referenced nowhere else in the
sources.
Alternatives, for completeness:
- Remove
extension-functions.c from the default build outright (breaking for consumers who
call these functions; presumably a major).
- Obtain an explicit license from the author and record it in the repository, if the functions
are considered worth keeping in the default build.
We are happy to open a PR for option 1 or 2 above if you tell us which shape you prefer.
The parent repository rhashimoto/wa-sqlite has the same file in its CFILES; we will
cross-reference an issue there.
Summary
Every
.wasmin the published npm package statically linksextension-functions.cfrom the SQLite contrib page. That file carries no copyright notice and no license grant
of any kind, so the published binaries contain third-party code whose redistribution terms
are undetermined.
This is easy to miss: the file is not vendored in this repository. It is downloaded during the
build (
Makefilelines 9–11 atcff99da), so source-level license scanning of the repo doesnot reveal it. It only shows up when the published artifacts are inspected.
We hit this during a license audit of a downstream product that ships these
.wasmfiles toend users' browsers via
@powersync/web.Where it comes from
Makefileatcff99da(master):It is in both
CFILESandMC_CFILES, so it ends up in every build variant. The SHA3-256 ofthe file we downloaded matches
EXTENSION_FUNCTIONS_SHA3, so we are looking at the same bytesthe build uses.
What the file says about its license
Nothing. A case-insensitive search over the 52,188-byte source returns zero occurrences of
copyright,license,licence,public domain,permission, andwarranty. The onlyattribution is a bare author line,
Liam Healy, followed by a change history. There is nogrant of rights and no statement placing it in the public domain.
The contrib page does not help either: the word "license"
does not appear on it, and the only entry that says anything about terms is a different one
(
sqlite_fk.tgz: "public domain source code"). So the page's authors do state terms when theyhave them, and for
extension-functions.cthey state none.SQLite itself being public domain does not extend to contributed files: the core is explicitly
dedicated to the public domain, whereas this file says nothing at all.
What the published packages actually contain
extension-functions.cregisters SQL functions that core SQLite does not provide(
strfilter,padc,padl,padr,leftstr,rightstr,proper,charindex,replicate,reverse,difference,median,variance,lower_quartile,upper_quartile, …). Their names survive in the.wasmdata section, so presence can beverified directly:
Results:
.wasmfiles@journeyapps/wa-sqlite@2.0.3@journeyapps/wa-sqlite@2.0.4(latest)wa-sqlite@1.0.0(rhashimoto)As a control, core-SQLite symbols such as
juliandayandsubstrare found in the same files,confirming the search method works.
Why this matters for the LICENSE file
package/LICENSEin the published tarball is:That correctly covers this project's own code, but the published
.wasmfiles also containcode authored by someone else, under no license. Consumers who comply with the MIT terms are
still left redistributing code they have no demonstrable permission to redistribute.
Is it actually used?
Not by PowerSync, as far as we can tell. We searched the published sources of
@powersync/web@2.2.0(125 files) and@powersync/common@2.2.0(150 files) for every functionname that only
extension-functions.cprovides and found no references. Our own applicationdoes not use them either.
We understand other consumers of this package may rely on these functions, which is why we
are not asking for them to be removed from the default build.
What we are asking for
Please offer a build of the artifacts that does not include
extension-functions.c, alongsidethe existing ones. Existing consumers keep exactly what they have today; consumers with a
license-compliance requirement can opt in.
Two shapes would work for us, and we would defer to whichever fits your release process better:
dist/artifacts in the same package — e.g.dist/wa-sqlite-noext.*,dist/mc-wa-sqlite-async-noext.*(naming is yours), built from aCFILES/MC_CFILESlist without
extension-functions.c. No new version line, no new package. Downstreamconsumers of
@powersync/webwould alias the fixed import paths invfs.jsto the-noextfiles.@journeyapps/wa-sqlitebuilt without the file.Downstream consumers would pin it via npm
overrides(since@powersync/webdepends on anexact version).
The change to the sources is small as far as we can see (static inspection only, not yet
built): drop
extension-functions.cfromCFILES(line 16) andMC_CFILES(line 30), drop"_RegisterExtensionFunctions"fromsrc/exported_functions.json(line 2), and skip theModule.ccall('RegisterExtensionFunctions', …)call insqlite3.open_v2(src/sqlite-api.jsline 526) for the variant.
RegisterExtensionFunctionsis referenced nowhere else in thesources.
Alternatives, for completeness:
extension-functions.cfrom the default build outright (breaking for consumers whocall these functions; presumably a major).
are considered worth keeping in the default build.
We are happy to open a PR for option 1 or 2 above if you tell us which shape you prefer.
The parent repository
rhashimoto/wa-sqlitehas the same file in itsCFILES; we willcross-reference an issue there.