Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
pull_request:
# The branches below must be a subset of the branches above
branches: ["master"]
# Skip kotoba-only PRs; those run .github/workflows/kotoba-v1.yml.
paths:
- 'java/**'
- 'javascript/**'
- 'cpp/**'
- 'resources/**'
- 'tools/**'
- 'pom.xml'
schedule:
- cron: "0 0 * * 1"

Expand All @@ -41,7 +49,7 @@

steps:
- name: Harden Runner
uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-g85v-wf27-67xc

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-mxr3-8whj-j74r

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-cpmj-h4f6-r6pq

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-g699-3x6g-wm3g

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-46g3-37rh-v698

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

codeql.yml:52: action has a known vulnerability: GHSA-g85v-wf27-67xc

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

codeql.yml:52: action has a known vulnerability: GHSA-mxr3-8whj-j74r

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

codeql.yml:52: action has a known vulnerability: GHSA-cpmj-h4f6-r6pq

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

codeql.yml:52: action has a known vulnerability: GHSA-g699-3x6g-wm3g

Check failure on line 52 in .github/workflows/codeql.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

codeql.yml:52: action has a known vulnerability: GHSA-46g3-37rh-v698
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs

Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/cpp-unit-test.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# This workflow builds and unit tests both main C++ API and also build/data tools for metadata generation.

name: Testing C++ API
on: pull_request
on:
pull_request:
# Skip kotoba-only PRs; those run .github/workflows/kotoba-v1.yml.
paths:
- 'cpp/**'
- 'tools/cpp/**'
- 'resources/**'
permissions:
contents: read

Expand All @@ -10,7 +16,7 @@
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-mxr3-8whj-j74r

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-cpmj-h4f6-r6pq

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-g699-3x6g-wm3g

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

zizmor/known-vulnerable-actions

action has a known vulnerability: GHSA-46g3-37rh-v698

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

cpp-unit-test.yml:19: action has a known vulnerability: GHSA-g85v-wf27-67xc

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

cpp-unit-test.yml:19: action has a known vulnerability: GHSA-mxr3-8whj-j74r

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

cpp-unit-test.yml:19: action has a known vulnerability: GHSA-cpmj-h4f6-r6pq

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

cpp-unit-test.yml:19: action has a known vulnerability: GHSA-g699-3x6g-wm3g

Check failure on line 19 in .github/workflows/cpp-unit-test.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

known-vulnerable-actions

cpp-unit-test.yml:19: action has a known vulnerability: GHSA-46g3-37rh-v698
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs

Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@
#
# Source repository: https://github.com/actions/dependency-review-action
name: 'Dependency Review'
on: [pull_request]
on:
pull_request:
# Skip kotoba-only PRs; those run .github/workflows/kotoba-v1.yml.
paths-ignore:
- 'kotoba/**'
- '.github/workflows/kotoba-v1.yml'
- '.github/workflows/java-unit-test.yml'
- '.github/workflows/cpp-unit-test.yml'
- '.github/workflows/codeql.yml'
- '.github/workflows/osv-scanner-unified.yml'
- '.github/workflows/dependency-review.yml'

permissions:
contents: read
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/java-unit-test.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# This workflow builds and unit tests both main Java API and also build/data tools for metadata generation.

name: Testing Java API
on: pull_request
on:
pull_request:
# Skip kotoba-only PRs; those run .github/workflows/kotoba-v1.yml.
paths:
- 'java/**'
- 'javascript/**'
- 'resources/**'
- 'tools/java/**'
- 'pom.xml'
permissions:
contents: read

Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/kotoba-v1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Kotoba v1

on:
push:
branches: [master]
paths:
- 'kotoba/**'
- '.github/workflows/kotoba-v1.yml'
pull_request:
paths:
- 'kotoba/**'
- '.github/workflows/kotoba-v1.yml'

permissions:
contents: read

jobs:
kotoba:
name: kotoba compile + fixture
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

- name: Install kotoba v0.7.2
shell: bash
run: |
set -euo pipefail
release_dir="$RUNNER_TEMP/kotoba-v0.7.2"
cli_dir="$RUNNER_TEMP/kotoba-cli"
mkdir -p "$release_dir" "$cli_dir"
curl -L --fail --silent --show-error \
-o "$release_dir/kotoba-linux-amd64.tar.gz" \
https://github.com/kotoba-lang/kotoba/releases/download/v0.7.2/kotoba-linux-amd64.tar.gz
curl -L --fail --silent --show-error \
-o "$release_dir/kotoba-linux-amd64.tar.gz.sha256" \
https://github.com/kotoba-lang/kotoba/releases/download/v0.7.2/kotoba-linux-amd64.tar.gz.sha256
(cd "$release_dir" && sha256sum -c kotoba-linux-amd64.tar.gz.sha256)
tar -xzf "$release_dir/kotoba-linux-amd64.tar.gz" -C "$cli_dir"
echo "$cli_dir" >> "$GITHUB_PATH"

- name: Compile wasm and run fixture
run: kotoba/checks.sh
9 changes: 9 additions & 0 deletions .github/workflows/osv-scanner-unified.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@
on:
pull_request:
branches: ["master"]
# Skip kotoba-only PRs; those run .github/workflows/kotoba-v1.yml.
paths-ignore:
- 'kotoba/**'
- '.github/workflows/kotoba-v1.yml'
- '.github/workflows/java-unit-test.yml'
- '.github/workflows/cpp-unit-test.yml'
- '.github/workflows/codeql.yml'
- '.github/workflows/dependency-review.yml'
- '.github/workflows/osv-scanner-unified.yml'
schedule:
- cron: "12 12 * * 1"
push:
Expand All @@ -27,7 +36,7 @@
# Required to upload SARIF file to CodeQL. See: https://github.com/github/codeql-action/issues/2117
actions: read
# Require writing security events to upload SARIF file to security tab
security-events: write

Check warning on line 39 in .github/workflows/osv-scanner-unified.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

excessive-permissions

osv-scanner-unified.yml:39: overly broad permissions: security-events: write is overly broad at the workflow level
# Read commit contents
contents: read

Expand Down
84 changes: 84 additions & 0 deletions kotoba/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Kotoba v1 for libphonenumber

First-class sibling tree to `cpp/`, `java/`, and `javascript/`. This directory
is a Kotoba check surface for the fork, not a language binding over the Java,
C++, or JavaScript libraries.

Public operator: awai.network. Sales: Ryo Awai.

License: Apache-2.0 (same as this repository).

## Honest scope

v1 checks whether a short hardcoded fixture is a **well-formed E.164-looking**
string: a plus prefix plus a digit length.

- First byte must be `+` (ASCII 43).
- Every following byte must be an ASCII digit `0`–`9`.
- Digit count must be in `2..15`.
- `15` is the ITU E.164 maximum for the complete international number.
- `2` is this repository's `PhoneNumberUtil.MIN_LENGTH_FOR_NSN`, applied
here to the complete digit string, not to a region national number.

Two accept fixtures and two reject fixtures are taken from this repository's
own testdata (`US_NUMBER` / `GB_NUMBER` in
`java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java`):

| fixture | bytes | expected |
|---|---|---|
| `fixtures/us-e164.txt` | `+16502530000` | accept (E.164 of US_NUMBER) |
| `fixtures/gb-e164.txt` | `+442070313000` | accept (E.164 of GB_NUMBER) |
| `fixtures/us-international.txt` | `+1 650 253 0000` | reject (INTERNATIONAL spaces) |
| `fixtures/us-nsn.txt` | `6502530000` | reject (national number, no plus) |

This is **not**:

- a drop-in replacement for the Java, C++, or JavaScript libraries
- full region metadata / carrier / geocoding / timezone lookup
- `isValidNumber`, `isPossibleNumber` against country ranges
- parse, format, AsYouType, matcher, or short-number support
- a copy of `resources/phonenumber.proto` or the metadata proto set
- an FFI or JNI/C++ driver

A full libphonenumber port will not fit on wasm32 i64-v1. That dialect has no
IEEE floats, no admitted byte-builder, and no host imports in the
host-independent profile. Shrinking to a plus-prefix digit-length check of a
few project fixtures is the smallest codec/header/fixture that still proves a
real accept and a real reject. The shrink is documented here, not stubbed.

## Module

`phonenumber.kotoba` is one compilation unit (`phonenumber.v1`).

| export | meaning |
|---|---|
| `e164-looking` | `1` if fixture `id` is E.164-looking, else `0` |
| `accept-us` / `accept-gb` | `1` if the matching accept fixture is admitted |
| `reject-spaces` / `reject-nsn` | `1` if the matching reject fixture is refused |
| `main` | `1` if both accepts and both rejects hold |

## Build (kotoba CLI v0.7.2)

Language authority: [kotoba-lang/kotoba-lang](https://github.com/kotoba-lang/kotoba-lang).
CLI: [kotoba-lang/kotoba](https://github.com/kotoba-lang/kotoba) tag **v0.7.2**.

```sh
kotoba compile kotoba/phonenumber.kotoba --target wasm --output phonenumber.wasm --json
```

Accept `kotoba.cli/ok?` true, `kotoba.cli/code` `emitted`,
`value-profile` `i64-v1`. The artifact is host-independent wasm32
(`wasm32-kotoba-v1`, `value-abi` `direct-v1`): no `kotoba:typed` imports, no
libphonenumber native code.

`kotoba compile --target wasm --run` is not used. The i64-v1 guest does not
match the kototama/chicory runner on v0.7.2. Fixture execution is
`--target web --run` (`js-kotoba-v1`), which still reports `value-profile`
`i64-v1`.

```sh
kotoba/checks.sh
```

Install the CLI from the v0.7.2 release tarball or
`brew tap kotoba-lang/kotoba && brew trust kotoba-lang/kotoba && brew install kotoba`.
123 changes: 123 additions & 0 deletions kotoba/checks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env bash
# Compile phonenumber.kotoba with kotoba 0.7.2 and assert accept/reject fixtures.
set -euo pipefail

root=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)
cd "$root"

if ! command -v kotoba >/dev/null 2>&1; then
echo "kotoba CLI is required (kotoba-lang/kotoba v0.7.2)" >&2
exit 1
fi

if ! command -v python3 >/dev/null 2>&1; then
echo "python3 is required to parse kotoba --json and check wasm/fixtures" >&2
exit 1
fi

work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT

python3 - "$root" <<'PY'
import pathlib, sys
root = pathlib.Path(sys.argv[1])
fixtures = {
"kotoba/fixtures/us-e164.txt": "+16502530000",
"kotoba/fixtures/gb-e164.txt": "+442070313000",
"kotoba/fixtures/us-international.txt": "+1 650 253 0000",
"kotoba/fixtures/us-nsn.txt": "6502530000",
}


def e164_looking(s: str) -> bool:
if not (3 <= len(s) <= 16):
return False
if s[0] != "+":
return False
return all("0" <= ch <= "9" for ch in s[1:])


for rel, expected in fixtures.items():
got = (root / rel).read_text().rstrip("\n")
if got != expected:
raise SystemExit("%s is %r, expected %r" % (rel, got, expected))

accept_us = e164_looking(fixtures["kotoba/fixtures/us-e164.txt"])
accept_gb = e164_looking(fixtures["kotoba/fixtures/gb-e164.txt"])
reject_spaces = not e164_looking(fixtures["kotoba/fixtures/us-international.txt"])
reject_nsn = not e164_looking(fixtures["kotoba/fixtures/us-nsn.txt"])
print("fixture independent")
print(" accept +16502530000", accept_us)
print(" accept +442070313000", accept_gb)
print(" reject +1 650 253 0000", reject_spaces)
print(" reject 6502530000", reject_nsn)
if not (accept_us and accept_gb and reject_spaces and reject_nsn):
raise SystemExit("independent E.164-looking predicate disagreed with fixture table")
PY

compile_json=$(kotoba compile kotoba/phonenumber.kotoba --target wasm --output "$work/phonenumber.wasm" --json)
COMPILE_JSON="$compile_json" WASM_PATH="$work/phonenumber.wasm" python3 <<'PY'
import json, os
wasm_path = os.environ["WASM_PATH"]
d = json.loads(os.environ["COMPILE_JSON"])
ok = d.get("kotoba.cli/ok?")
code = d.get("kotoba.cli/code")
data = d.get("kotoba.cli/data") or {}
profile = data.get("value-profile")
compat = data.get("compatibility") or {}
print("wasm", ok, code, "profile", profile, "abi", compat.get("value-abi"), "target", compat.get("target"))
if not ok or code != "emitted":
raise SystemExit(d.get("kotoba.cli/message") or "wasm compile failed")
if profile != "i64-v1":
raise SystemExit("expected value-profile i64-v1, got %r" % (profile,))
if compat.get("value-abi") != "direct-v1":
raise SystemExit("expected value-abi direct-v1")
if compat.get("target") != "wasm32-kotoba-v1":
raise SystemExit("expected target wasm32-kotoba-v1")
blob = open(wasm_path, "rb").read()
if blob[:4] != b"\x00asm":
raise SystemExit("not wasm magic")

def read_u32(buf, i):
n = 0
shift = 0
while True:
b = buf[i]
i += 1
n |= (b & 0x7F) << shift
if b < 0x80:
return n, i
shift += 7

i = 8
imports = False
while i < len(blob):
sid = blob[i]
i += 1
size, i = read_u32(blob, i)
if sid == 2:
imports = True
i += size
if imports:
raise SystemExit("wasm has an import section; host-independent i64-v1 must not")
print("wasm host-independent", len(blob), "bytes")
PY

run_json=$(kotoba compile kotoba/phonenumber.kotoba --target web --output "$work/phonenumber.mjs" --run --json)
RUN_JSON="$run_json" python3 <<'PY'
import json, os
d = json.loads(os.environ["RUN_JSON"])
ok = d.get("kotoba.cli/ok?")
code = d.get("kotoba.cli/code")
data = d.get("kotoba.cli/data") or {}
result = data.get("result")
profile = data.get("value-profile")
print("web", ok, code, "result", result, "profile", profile)
if not ok or code != "ran":
raise SystemExit(d.get("kotoba.cli/message") or "web fixture run failed")
if profile != "i64-v1":
raise SystemExit("expected value-profile i64-v1 on web run")
if result != 1:
raise SystemExit("main returned %r, expected 1 (accept US/GB and reject spaces/NSN)" % (result,))
print("accept/reject fixture match ok")
PY
1 change: 1 addition & 0 deletions kotoba/fixtures/gb-e164.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
+442070313000
1 change: 1 addition & 0 deletions kotoba/fixtures/us-e164.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
+16502530000
1 change: 1 addition & 0 deletions kotoba/fixtures/us-international.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
+1 650 253 0000
1 change: 1 addition & 0 deletions kotoba/fixtures/us-nsn.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6502530000
Loading
Loading