Using Denos libxml2_xpath in a Pipline Application fails even under docker
running
docker run
\--interactive \\
\--tty \\
\--platform linux/amd64
\--rm
\--volume $PWD:/app
\--volume $HOME/.deno:/deno-dir
\--workdir /app
deno deno run --allow-read --allow-ffi --unstable examples/parse-xcb.ts
fails by
error: Uncaught (in promise) TypeError: Invalid FFI pointer type, expected null, or External
this.#ptr = lib.symbols.xmlCreatePushParserCtxt(
^
at new PushParseCtxt (https://deno.land/x/libxml2_xpath@v0.0.3/mod.ts:89:29)
at parseDocument (https://deno.land/x/libxml2_xpath@v0.0.3/mod.ts:442:17)
at eventLoopTick (ext:core/01_core.js:183:11)
at async file:///app/examples/parse-xcb.ts:9:15
Dockefile on Macbook M1
FROM --platform=linux/amd64 denoland/deno:1.37.0
RUN DEBIAN_FRONTEND=noninteractive \
apt-get update \
&& apt-get install -qy \
libxml2-utils \
libxml2-dev \
libxml2
That third-party lib is outdated (https://deno.land/x/libxml2_xpath), it's using pointer
type when it should be buffer
since it's passing a Uint8Array
https://docs.deno.com/runtime/manual/runtime/ffi_api#supported-types
As of Deno 1.25, the pointer type has been split into a pointer and a buffer type to ensure users take advantage of optimizations for Typed Arrays, and as of Deno 1.31 the JavaScript representation of pointer has become an opaque pointer object or null for null pointers.
Once you change the source from that lib from:
"xmlCreatePushParserCtxt": {
parameters: ["pointer", "pointer", "pointer", "usize", "pointer"],
result: "pointer",
nonblocking: false,
},
to:
"xmlCreatePushParserCtxt": {
parameters: ["pointer", "pointer", "buffer", "usize", "buffer"],
result: "pointer",
nonblocking: false,
},
You no longer encounter that error. However, other errors get triggered because the library is quite outdated. It uses the unstable FFI API, which requires that the project be kept up to date.
If you then change the constructor to:
constructor(chunk: Uint8Array) {
this.#ptr = lib.symbols.xmlCreatePushParserCtxt(
null,
null,
chunk,
chunk.length,
cstr("<mem>"),
);
if (typeof this.#ptr !== 'object') {
throw new Error(`${this.#ptr}`);
}
}
The lib no longer crashes when calling parseDocument(stream)
. But it crashes when using XPathContext(doc)
. It won't work until you replace all the outdated FFI types.
You should find a new library or update that one completely.