Skip to main content

As JavaScript Library

Describes how to use recheck as a JavaScript/TypeScript library.

Install

npm

The NPM package of recheck is named recheck simply. You can install the package with the following command.

npm install recheck

Finished the installation, you are going to play with the recheck.

Usage

recheck exposes two methods: check and checkSync. check is an asynchronous version of the entry point of this library. checkSync is similar to check, but it is the synchronous version. As stated below, check invokes the external CLI command as backend if possible, so it is faster and more useful than the checkSync, thus we recommend using the check.

See the below TypeScript API definition (The entire d.ts file is here).

export function check(
source: string,
flags: string,
params?: Parameters & HasAbortSignal,
): Promise<Diagnostics>;

export function checkSync(
source: string,
flags: string,
params?: Parameters,
): Diagnostics;

The first argument source is a source string of RegExp (corresponding to RegExp.prototype.source in JavaScript). And, the second argument flags is a flags string of RegExp (corresponding to RegExp.prototype.flags in JavaScript too). The third optional argument params is an object of parameters to specify checker behavior.

To check the ReDoS vulnerability in /^(a|a)*$/, then you should use this library in such a following way.

import { check } from "recheck";

await check("^(a|a)*$", "");
info

See this page for detailed information on Parameters value.

The result value of the check is called Diagnostics. Though it has many fields, the most important one is status. This field takes one of the three values.

  • 'safe' means the given regular expression seems safe at least in this checking.
  • 'vulnerable' means vulnerability in the given regular expression is found.
  • 'unknown' means something wrong happened in checking (timeout, cancel, or error).
info

See this page for detailed information on Diagnostics value.

Cancel

The third argument check has the HasAbortSignal type. This type has the following signature.

export type HasAbortSignal = {
signal?: AbortSignal;
};

AbortSignal is the standard Web API to abort some operations (If you don’t know this, please see the MDN document.) You can use this like in the standard way.

import { check } from "recheck";

const controller = new AbortController();
const signal = controller.signal;

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

// Aborts `check` after 100 ms if it is not finished.
await Promise.all([
check("^a+a+$", "", { signal }),
sleep(100).then(() => controller.abort()),
]);
caution

There is the timeout parameter to specify timeout seconds. Please use this instead of the manual way.

note

The signal parameter works only on the external CLI command backend. If you use pure JavaScript backend or for the same reason synchronous API, the signal parameter is ignored simply.

Backend

RECHECK_BACKEND

The JavaScript library is just a wrapper for the recheck CLI and Scala.js build. You can specify the backend via the RECHECK_BACKEND environment variable. There are four options to the RECHECK_BACKEND value.

  • RECHECK_BACKEND=auto (default)

    Tries native and java backends sequentially. If there is a possible backend, it uses this. Otherwise, it uses worker backend as a fallback.

  • RECHECK_BACKEND=native

    Uses the Graal native-image build contained by recheck-${os}-${arch} package. When the platform is not supported, it will be failed. The following table shows supported platforms.

    package nameOSCPU
    recheck-linux-x64Linuxx86-64
    recheck-macos-x64macOSx86-64
    recheck-windows-x64Windowsx86-64

    You can specify the binary path via the RECHECK_BIN environment variable manually.

  • RECHECK_BACKEND=java

    Uses the JAR build contained by the recheck-jar package with the java command. When the system does not have the java command, it will be failed.

    This backend is a bit slow for starting up, but the checking time is expected to be faster than other backends if the process lives a long time.

    You can specify the archive path via the RECHECK_JAR environment variable manually.

  • RECHECK_BACKEND=worker

    Uses the Scala.js build embedded in the recheck package with running on the Web Worker or worker_threads module.

    It does not block the main process, but it still has some restriction.

  • RECHECK_BACKEND=pure

    Uses the Scala.js build embedded in the recheck package with running on the main thread.

    This is the last resort backend. It blocks the process, but we expect this backend works everywhere.

The java and native backends are the external CLI command backend. They have some better features than the worker and pure backend.

  • Supports the signal parameter to cancel checking. worker also supports this feature.
  • Supports recall validation. worker backend does not support this feature for now.
  • Checks in true asynchronous. Although we can use the pure as a backend of the asynchronous API, it blocks the process, unfortunately. However, worker does not.
  • Works with multiple threads. On the external CLI command backend, it can check multiple regular expressions at once.

RECHECK_SYNC_BACKEND

Similarly, RECHECK_SYNC_BACKEND specifies the backend of synchronous API checkSync.

  • RECHECK_SYNC_BACKEND=synckit

    Uses synckit for working asynchronous check as synchronous. RECHECK_BACKEND is also used in forked thread.

  • RECHECK_SYNC_BACKEND=pure

    Same as the RECHECK_BACKEND one.

Use on Browser

recheck package supports the browser environment of course. It only supports the worker and pure backend because browsers cannot spawn the external command.

check uses worker backend at any time, and checkSync uses pure backend. We cannot switch the backend by the some environment variables for now.

The bundle for browsers is named lib/browser.js in the recheck package, and package.json has the browser field. Most bundlers (webpack, rollup, parcel, etc) support this field, but additional configurations may be needed.