This commit is contained in:
SheetJS 2023-09-24 15:48:44 -04:00
parent 74312fbaf4
commit 1b7dde139d
5 changed files with 105 additions and 17 deletions

2
.gitignore vendored

@ -1,3 +1,5 @@
package-lock.json
# Logs
logs
*.log

@ -6,6 +6,10 @@ build:
dev:
npm run dev -- --host
.PHONY: init
init:
npm i
.PHONY: deps
deps:
# protos

@ -65,17 +65,81 @@ copy the raw byte representation (array of numbers) or parsed object (JSON).
## Development
### Website
`make dev` starts the dev server.
`make build` generates the static site.
## Refreshing Protos and Messages
`make init` installs dependencies.
`make deps` requires a SIP-disabled Intel Mac with Keynote + Numbers + Pages.
### Protos and Messages
`make deps` requires a SIP-disabled Mac with Keynote + Numbers + Pages.
The last run was on 2023-09-24 against version 13.2 (7038.0.87)
Each app should be run at least once before refreshing artifacts.
#### Software License Agreements
Before refreshing, each app must be launched once and the software license
agreements must be accepted.
In the 13.2 update, Keynote clearly states
> By clicking Continue you agree to the terms of the Keynote Software License Agreement
Curiously, the Numbers "What's New in Numbers" popup does not have a similar
disclaimer. It is suspected that clicking "Continue" in Numbers and Pages serves
a similar purpose.
#### Disabling SIP
1) Enter Recovery mode:
On Intel Macs, shut down and restart while holding down Command+R keys.
On Apple Silicon Macs, shut down and restart while holding down the Touch ID.
It will display a message "Continue holding for startup options". Let go once
the message changes to "Loading startup options"
Select "Options" in the boot window and click the "Continue" button.
2) Open a terminal window (Utilities > Terminal) and run the following command:
```
csrutil disable
```
If there is no error, restart the machine.
**Apple Silicon Extra Steps**
If the command fails with a message like
```
csrutil: The OS environment does not allow changing security configuration options.
Ensure that the system was booted into Recovery OS via the standard user action.
```
3) Run the following command:
```
csrutil clear
```
4) Open the "Startup Security Utility" (in the Utilities menu)
5) Click "Security Policy..." and select "Permissive Security". Click "OK".
6) Reboot into recovery mode (explained in Step 1)
7) Open a terminal window (Utilities > Terminal) and run:
```
csrutil disable
```
**Remember to re-enable SIP after updating messages!**
#### Developer Tools error
@ -85,10 +149,13 @@ Note: Runs may fail with an error like
error: Uncaught (in promise) "Could not find map!"
```
Developer tools permissions must be granted. Running the command a second time
typically shows a popup asking for Touch ID or password. After authorization,
the build should run successfully.
Running the command a second time typically shows a popup:
"""
Developer Tools Access needs to take control of another process for debugging to continue
"""
It will ask for Touch ID or password. After authorization, the build should run.
## Protocol Buffer Details

@ -2,26 +2,36 @@
/*! dump_registry.ts (C) 2022-present SheetJS LLC -- https://sheetjs.com */
/*
NOTE: this script requires an Intel Mac, Numbers, LLDB, and Deno
NOTE: this script requires a SIP-disabled Mac, Numbers, LLDB, and Deno
USAGE: deno run -A https://oss.sheetjs.com/notes/iwa/dump_registry.ts
*/
if(Deno.build.os != "darwin") throw `Must run in macOS!`;
if(Deno.build.arch != "x86_64") throw `Must run on Intel Mac (Apple Silicon currently unsupported)`;
const arch_map = {
"x86_64": "x86_64",
"aarch64": "arm64"
};
if(!arch_map[Deno.build.arch]) throw `Unsupported architecture ${Deno.build.arch}`;
const cmd = Deno?.args?.[0] || "/Applications/Numbers.app/Contents/MacOS/Numbers";
try { Deno.statSync(cmd); } catch(e) { throw `Could not find ${cmd}!`; }
/* test if SIP is disabled */
{
const p = Deno.run({cmd:["csrutil","status"],stdin:"piped",stdout:"piped" });
const [status, stdout] = await Promise.all([ p.status(), p.output() ]);
await p.close();
const data = new TextDecoder().decode(stdout);
//if(data.includes("enabled")) throw `SIP must be disabled!`;
if(!data.includes("disabled")) throw `SIP must be disabled!`;
}
const p = Deno.run({ cmd: `lldb ${Deno?.args?.[0] || "/Applications/Numbers.app/Contents/MacOS/Numbers"} -a x86_64`.split(" "),
stdin: "piped", stdout: "piped"
});
/* start debugger */
const p = Deno.run({ cmd: `lldb ${cmd} -a ${arch_map[Deno.build.arch]}`.split(" "), stdin: "piped", stdout: "piped" });
/* run commands */
const doit = (x: string) => p?.stdin?.write(new TextEncoder().encode(x))
const cmds = [
@ -37,21 +47,26 @@ const cmds = [
for(const cmd of cmds) await doit(cmd + "\n");
/* LLDB does not exit normally, setTimeout workaround */
setTimeout(() => p.kill("SIGKILL"), 15000)
setTimeout(() => p.kill("SIGKILL"), 30000)
/* wait for debugger */
const [status, stdout] = await Promise.all([ p.status(), p.output() ]);
await p.close();
/* search for _messageTypeToPrototypeMap */
const data = new TextDecoder().decode(stdout);
const res = data.match(/_messageTypeToPrototypeMap = {([^]*?)}/m)?.[1];
if(!res) throw `Could not find map!`
if(!res) throw `Could not find map!`;
/* extract records and sort by ID */
const rows = res.split(/[\r\n]+/).map(r => r.trim().split(/\s+/)).filter(x => x.length > 1);
rows.sort((l, r) => +l[0] - +r[0]);
/* emit code */
console.log(`export default {`);
rows.forEach(r => {
/* setDeprecatedMessageType */
if(r[3] == "null") return;
console.log(` ${r[0]}: ".${r[3]}",`);
});
console.log(`} as {[key: number]: string};`);
//console.log(Object.fromEntries(rows.map(r => [r[0], r[3]]).filter(r => r[1] != "null")));

@ -372,7 +372,7 @@ function process(data: Uint8Array, message: string, protos: any) {
switch(freq) {
case "repeated": {
if(/packed\s*=\s*true/.test(line)) {
/* these are the known types as of iwa 13.0 */
/* these are the known types as of iwa 13.2 */
switch(type) {
case "uint32": out[name] = parse_packed_varints(shallow[i][0].data); break;
case "uint64": out[name] = parse_packed_varint64(shallow[i][0].data); break;