import path from 'node:path'
import type { IncomingMessage, Server } from 'node:http'
import { STATUS_CODES, createServer as createHttpServer } from 'node:http'
import type { ServerOptions as HttpsServerOptions } from 'node:https'
import { createServer as createHttpsServer } from 'node:https'
import type { Socket } from 'node:net'
import type { Duplex } from 'node:stream'
import crypto from 'node:crypto'
import colors from 'picocolors'
import type { WebSocket as WebSocketRaw } from 'ws'
import { WebSocketServer as WebSocketServerRaw_ } from 'ws'
import { isHostAllowed } from 'host-validation-middleware'
import type { WebSocket as WebSocketTypes } from '#dep-types/ws'
import type {
  ErrorPayload,
  FullReloadPayload,
  HotPayload,
} from '#types/hmrPayload'
import type { InferCustomEventPayload } from '#types/customEvent'
import type { ResolvedConfig } from '..'
import { isObject } from '../utils'
import type { NormalizedHotChannel, NormalizedHotChannelClient } from './hmr'
import { normalizeHotChannel } from './hmr'
import type { HttpServer } from '.'

/* In Bun, the `ws` module is overridden to hook into the native code. Using the bundled `js` version
 * of `ws` will not work as Bun's req.socket does not allow reading/writing to the underlying socket.
 */
const WebSocketServerRaw = process.versions.bun
  ? // @ts-expect-error: Bun defines `import.meta.require`
    import.meta.require('ws').WebSocketServer
  : WebSocketServerRaw_

export const HMR_HEADER = 'vite-hmr'

export type WebSocketCustomListener<T> = (
  data: T,
  client: WebSocketClient,
) => void

export const isWebSocketServer: unique symbol = Symbol('isWebSocketServer')

export interface WebSocketServer extends NormalizedHotChannel {
  /**
   * Handle custom event emitted by `import.meta.hot.send`
   */
  on: WebSocketTypes.Server['on'] & {
    <T extends string>(
      event: T,
      listener: WebSocketCustomListener<InferCustomEventPayload<T>>,
    ): void
  }
  /**
   * Unregister event listener.
   */
  off: WebSocketTypes.Server['off'] & {
    (event: string, listener: Function): void
  }
  /**
   * Listen on port and host
   */
  listen(): void
  /**
   * Disconnect all clients and terminate the server.
   */
  close(): Promise<void>

  [isWebSocketServer]: true
  /**
   * Get all connected clients.
   */
  clients: Set<WebSocketClient>
}

export interface WebSocketClient extends NormalizedHotChannelClient {
  /**
   * The raw WebSocket instance
   * @advanced
   */
  socket: WebSocketTypes
}

const wsServerEvents = [
  'connection',
  'error',
  'headers',
  'listening',
  'message',
]

function noop() {
  // noop
}

// we only allow websockets to be connected if it has a valid token
// this is to prevent untrusted origins to connect to the server
// for example, Cross-site WebSocket hijacking
//
// we should check the token before calling wss.handleUpgrade
// otherwise untrusted ws clients will be included in wss.clients
//
// using the query params means the token might be logged out in server or middleware logs
// but we assume that is not an issue since the token is regenerated for each process
function hasValidToken(config: ResolvedConfig, url: URL) {
  const token = url.searchParams.get('token')
  if (!token) return false

  try {
    const isValidToken = crypto.timingSafeEqual(
      Buffer.from(token),
      Buffer.from(config.webSocketToken),
    )
    return isValidToken
  } catch {} // an error is thrown when the length is incorrect
  return false
}

export function createWebSocketServer(
  server: HttpServer | null,
  config: ResolvedConfig,
  httpsOptions?: HttpsServerOptions,
): WebSocketServer {
  if (config.server.ws === false) {
    return {
      [isWebSocketServer]: true,
      get clients() {
        return new Set<WebSocketClient>()
      },
      async close() {
        // noop
      },
      on: noop as any as WebSocketServer['on'],
      off: noop as any as WebSocketServer['off'],
      setInvokeHandler: noop,
      handleInvoke: async () => ({
        error: {
          name: 'TransportError',
          message: 'handleInvoke not implemented',
          stack: new Error().stack,
        },
      }),
      listen: noop,
      send: noop,
    }
  }

  let wsHttpServer: Server | undefined = undefined

  const wsOptions = isObject(config.server.ws) ? config.server.ws : undefined
  const wsCustomServer = wsOptions?.server
  const wsPort = wsOptions?.port
  // TODO: the main server port may not have been chosen yet as it may use the next available
  const portsAreCompatible = !wsPort || wsPort === config.server.port
  const wsServer = wsCustomServer || (portsAreCompatible && server)
  let hmrServerWsListener: (
    req: InstanceType<typeof IncomingMessage>,
    socket: Duplex,
    head: Buffer,
  ) => void
  const customListeners = new Map<string, Set<WebSocketCustomListener<any>>>()
  const clientsMap = new WeakMap<WebSocketRaw, WebSocketClient>()
  const port = wsPort || 24678
  const host = wsOptions?.host || undefined
  const allowedHosts =
    config.server.allowedHosts === true
      ? config.server.allowedHosts
      : Object.freeze([...config.server.allowedHosts]) // Freeze the array to allow caching

  const shouldHandle = (req: IncomingMessage) => {
    const protocol = req.headers['sec-websocket-protocol']!
    // vite-ping is allowed to connect from anywhere
    // because it needs to be connected before the client fetches the new `/@vite/client`
    // this is fine because vite-ping does not receive / send any meaningful data
    if (protocol === 'vite-ping') return true

    if (
      allowedHosts !== true &&
      !isHostAllowed(req.headers.host, allowedHosts)
    ) {
      return false
    }

    if (config.legacy?.skipWebSocketTokenCheck) {
      return true
    }

    // If the Origin header is set, this request might be coming from a browser.
    // Browsers always sets the Origin header for WebSocket connections.
    if (req.headers.origin) {
      const parsedUrl = new URL(`http://example.com${req.url!}`)
      return hasValidToken(config, parsedUrl)
    }

    // We allow non-browser requests to connect without a token
    // for backward compat and convenience
    // This is fine because if you can sent a request without the SOP limitation,
    // you can also send a normal HTTP request to the server.
    return true
  }
  const handleUpgrade = (
    req: IncomingMessage,
    socket: Duplex,
    head: Buffer,
    isPing: boolean,
  ) => {
    wss.handleUpgrade(req, socket as Socket, head, (ws) => {
      // vite-ping is allowed to connect from anywhere
      // we close the connection immediately without connection event
      // so that the client does not get included in `wss.clients`
      if (isPing) {
        ws.close(/* Normal Closure */ 1000)
        return
      }
      wss.emit('connection', ws, req)
    })
  }
  const wss: WebSocketServerRaw_ = new WebSocketServerRaw({ noServer: true })
  wss.shouldHandle = shouldHandle

  if (wsServer) {
    let hmrBase = config.base
    const wsPath = wsOptions?.path
    if (wsPath) {
      hmrBase = path.posix.join(hmrBase, wsPath)
    }
    hmrServerWsListener = (req, socket, head) => {
      const protocol = req.headers['sec-websocket-protocol']!
      const parsedUrl = new URL(`http://example.com${req.url!}`)
      if (
        [HMR_HEADER, 'vite-ping'].includes(protocol) &&
        parsedUrl.pathname === hmrBase
      ) {
        handleUpgrade(req, socket as Socket, head, protocol === 'vite-ping')
      }
    }
    wsServer.on('upgrade', hmrServerWsListener)
  } else {
    // http server request handler keeps the same with
    // https://github.com/websockets/ws/blob/45e17acea791d865df6b255a55182e9c42e5877a/lib/websocket-server.js#L88-L96
    const route = ((_, res) => {
      const statusCode = 426
      const body = STATUS_CODES[statusCode]
      if (!body)
        throw new Error(`No body text found for the ${statusCode} status code`)

      res.writeHead(statusCode, {
        'Content-Length': body.length,
        'Content-Type': 'text/plain',
      })
      res.end(body)
    }) as Parameters<typeof createHttpServer>[1]
    // vite dev server in middleware mode
    // need to call ws listen manually
    if (httpsOptions) {
      wsHttpServer = createHttpsServer(httpsOptions, route)
    } else {
      wsHttpServer = createHttpServer(route)
    }
    wsHttpServer.on('upgrade', (req, socket, head) => {
      const protocol = req.headers['sec-websocket-protocol']!
      if (protocol === 'vite-ping' && server && !server.listening) {
        // reject connection to tell the vite/client that the server is not ready
        // if the http server is not listening
        // because the ws server listens before the http server listens
        req.destroy()
        return
      }
      handleUpgrade(req, socket as Socket, head, protocol === 'vite-ping')
    })
    wsHttpServer.on('error', (e: Error & { code: string; port: number }) => {
      if (e.code === 'EADDRINUSE') {
        config.logger.error(
          colors.red(
            `WebSocket server error: Port ${e.port} is already in use`,
          ),
          { error: e },
        )
      } else {
        config.logger.error(
          colors.red(`WebSocket server error:\n${e.stack || e.message}`),
          { error: e },
        )
      }
    })
  }

  const emitCustomEvent = <T extends string>(
    event: T,
    data: InferCustomEventPayload<T>,
    socket: WebSocketRaw,
  ) => {
    const listeners = customListeners.get(event)
    if (!listeners?.size) return

    const client = getSocketClient(socket)
    for (const listener of listeners) {
      listener(data, client)
    }
  }

  wss.on('connection', (socket) => {
    socket.on('message', (raw) => {
      if (!customListeners.size) return
      let parsed: any
      try {
        parsed = JSON.parse(String(raw))
      } catch {}
      if (!parsed || parsed.type !== 'custom' || !parsed.event) return
      emitCustomEvent(parsed.event, parsed.data, socket)
    })
    socket.on('error', (err) => {
      config.logger.error(`${colors.red(`ws error:`)}\n${err.stack}`, {
        timestamp: true,
        error: err,
      })
    })
    socket.on('close', () => {
      emitCustomEvent('vite:client:disconnect', undefined, socket)
    })

    emitCustomEvent('vite:client:connect', undefined, socket)

    socket.send(JSON.stringify({ type: 'connected' }))
    if (bufferedMessage) {
      socket.send(JSON.stringify(bufferedMessage))
      bufferedMessage = null
    }
  })

  wss.on('error', (e: Error & { code: string; port: number }) => {
    if (e.code === 'EADDRINUSE') {
      config.logger.error(
        colors.red(`WebSocket server error: Port ${e.port} is already in use`),
        { error: e },
      )
    } else {
      config.logger.error(
        colors.red(`WebSocket server error:\n${e.stack || e.message}`),
        { error: e },
      )
    }
  })

  // Provide a wrapper to the ws client so we can send messages in JSON format
  // To be consistent with server.ws.send
  function getSocketClient(socket: WebSocketRaw) {
    if (!clientsMap.has(socket)) {
      clientsMap.set(socket, {
        send: (...args: any[]) => {
          let payload: HotPayload
          if (typeof args[0] === 'string') {
            payload = {
              type: 'custom',
              event: args[0],
              data: args[1],
            }
          } else {
            payload = args[0]
          }
          socket.send(JSON.stringify(payload))
        },
        socket,
      })
    }
    return clientsMap.get(socket)!
  }

  // On page reloads, if a file fails to compile and returns 500, the server
  // sends the error payload before the client connection is established.
  // If we have no open clients, buffer the error and send it to the next
  // connected client.
  // The same thing may happen when the optimizer runs fast enough to
  // finish the bundling before the client connects.
  let bufferedMessage: ErrorPayload | FullReloadPayload | null = null

  const normalizedHotChannel = normalizeHotChannel(
    {
      send(payload) {
        if (
          (payload.type === 'error' || payload.type === 'full-reload') &&
          !wss.clients.size
        ) {
          bufferedMessage = payload
          return
        }

        const stringified = JSON.stringify(payload)
        wss.clients.forEach((client) => {
          // readyState 1 means the connection is open
          if (client.readyState === 1) {
            client.send(stringified)
          }
        })
      },
      on(event: string, fn: any) {
        if (!customListeners.has(event)) {
          customListeners.set(event, new Set())
        }
        customListeners.get(event)!.add(fn)
      },
      off(event: string, fn: any) {
        customListeners.get(event)?.delete(fn)
      },
      listen() {
        wsHttpServer?.listen(port, host)
      },
      close() {
        // should remove listener if hmr.server is set
        // otherwise the old listener swallows all WebSocket connections
        if (hmrServerWsListener && wsServer) {
          wsServer.off('upgrade', hmrServerWsListener)
        }
        return new Promise<void>((resolve, reject) => {
          wss.clients.forEach((client) => {
            client.terminate()
          })
          wss.close((err) => {
            if (err) {
              reject(err)
            } else {
              if (wsHttpServer) {
                wsHttpServer.close((err) => {
                  if (err) {
                    reject(err)
                  } else {
                    resolve()
                  }
                })
              } else {
                resolve()
              }
            }
          })
        })
      },
    },
    config.server.hmr !== false,
    // Don't normalize client as we already handles the send, and to keep `.socket`
    false,
  )
  return {
    ...normalizedHotChannel,

    on: ((event: string, fn: any) => {
      if (wsServerEvents.includes(event)) {
        wss.on(event, fn)
        return
      }
      normalizedHotChannel.on(event, fn)
    }) as WebSocketServer['on'],
    off: ((event: string, fn: any) => {
      if (wsServerEvents.includes(event)) {
        wss.off(event, fn)
        return
      }
      normalizedHotChannel.off(event, fn)
    }) as WebSocketServer['off'],
    async close() {
      await normalizedHotChannel.close()
    },

    [isWebSocketServer]: true,
    get clients() {
      return new Set(Array.from(wss.clients).map(getSocketClient))
    },
  }
}


import { describe, expect, test } from 'vitest'
import {
  findAssetFile,
  getColor,
  isBuild,
  isBundled,
  isBundledDev,
  listAssets,
  page,
  readFile,
  readManifest,
} from '~utils'

test('should load the worker', async () => {
  await expect.poll(() => page.textContent('.worker-message')).toMatch('module')
})

test('should work', async () => {
  await expect.poll(() => page.textContent('#app')).toMatch('Hello')
})

// bundled dev: import.meta.env.LEGACY is not replaced — needs a fix in vite's
// legacy-env define handling (vitejs/vite#23028)
test.skipIf(isBundledDev)('import.meta.env.LEGACY', async () => {
  await expect
    .poll(() => page.textContent('#env'))
    .toMatch(isBuild ? 'true' : 'false')
  await expect.poll(() => page.textContent('#env-equal')).toMatch('true')
})

// https://github.com/vitejs/vite/issues/3400
test('transpiles down iterators correctly', async () => {
  await expect.poll(() => page.textContent('#iterators')).toMatch('hello')
})

test('async generator', async () => {
  await expect
    .poll(() => page.textContent('#async-generator'))
    .toMatch('[0,1,2]')
})

test('wraps with iife', async () => {
  await expect
    .poll(() => page.textContent('#babel-helpers'))
    .toMatch('exposed babel helpers: false')
})

test('generates assets', async () => {
  await expect
    .poll(() => page.textContent('#assets'))
    .toMatch(
      isBuild
        ? [
            'index: text/html',
            'index-legacy: text/html',
            'chunk-async: text/html',
            'chunk-async-legacy: text/html',
            'immutable-chunk: text/javascript',
            'immutable-chunk-legacy: text/javascript',
            'polyfills-legacy: text/html',
          ].join('\n')
        : isBundledDev
          ? [
              // bundled dev serves the entry at /assets/index.js. That name
              // has no hash, so the request finds it and gets JavaScript.
              // Legacy chunks do not exist at all, because the legacy plugin
              // only runs on build.
              // Every other chunk name has a hash. A request for the plain
              // name finds nothing and falls back to index.html.
              // `immutable-chunk` gets a hash here too, because the dev bundle
              // ignores `build.rolldownOptions.output` naming. Whether it
              // should ignore it is still undecided (vitejs/vite#23028).
              'index: text/javascript',
              'index-legacy: text/html',
              'chunk-async: text/html',
              'chunk-async-legacy: text/html',
              'immutable-chunk: text/html',
              'immutable-chunk-legacy: text/html',
              'polyfills-legacy: text/html',
            ].join('\n')
          : [
              'index: text/html',
              'index-legacy: text/html',
              'chunk-async: text/html',
              'chunk-async-legacy: text/html',
              'immutable-chunk: text/html',
              'immutable-chunk-legacy: text/html',
              'polyfills-legacy: text/html',
            ].join('\n'),
    )
})

test('correctly emits styles', async () => {
  expect(await getColor('#app')).toBe('red')
})

// dynamic import css
test('should load dynamic import with css', async () => {
  await page.click('#dynamic-css-button')
  await expect.poll(() => getColor('#dynamic-css')).toBe('red')
})

test('asset url', async () => {
  expect(await page.textContent('#asset-path')).toMatch(
    isBundled ? /\/assets\/vite-[-\w]+\.svg/ : '/vite.svg',
  )
})

describe.runIf(isBuild)('build', () => {
  test('should generate correct manifest', async () => {
    const manifest = readManifest()
    // legacy polyfill
    expect(manifest['../../vite/legacy-polyfills-legacy']).toBeDefined()
    expect(manifest['../../vite/legacy-polyfills-legacy'].src).toBe(
      '../../vite/legacy-polyfills-legacy',
    )
    expect(manifest['custom0-legacy.js'].file).toMatch(
      /chunk-X-legacy\.[-\w]{8}.js/,
    )
    expect(manifest['custom1-legacy.js'].file).toMatch(
      /chunk-X-legacy-[-\w]{8}.js/,
    )
    expect(manifest['custom2-legacy.js'].file).toMatch(
      /chunk-X-legacy[-\w]{8}.js/,
    )
    // modern polyfill
    expect(manifest['../../vite/legacy-polyfills']).toBeDefined()
    expect(manifest['../../vite/legacy-polyfills'].src).toBe(
      '../../vite/legacy-polyfills',
    )
  })

  test('should minify legacy chunks', async () => {
    // This is a ghetto heuristic, but Oxc output seems to reliably include
    // this code
    const terserPattern = /,function\(e,/

    expect(findAssetFile(/chunk-async-legacy/)).toMatch(terserPattern)
    expect(findAssetFile(/chunk-async(?!-legacy)/)).not.toMatch(terserPattern)
    expect(findAssetFile(/immutable-chunk-legacy/)).toMatch(terserPattern)
    expect(findAssetFile(/immutable-chunk(?!-legacy)/)).not.toMatch(
      terserPattern,
    )
    expect(findAssetFile(/index-legacy/)).toMatch(terserPattern)
    expect(findAssetFile(/index(?!-legacy)/)).not.toMatch(terserPattern)
    expect(findAssetFile(/polyfills-legacy/)).toMatch(terserPattern)
  })

  test('should not use newer syntax when minifying legacy chunks', () => {
    // The playground targets IE 11, so babel lowers the legacy chunks to ES5.
    // The minifier must not reintroduce syntax newer than its `es2015` compress
    // target: `try {} catch (e) {}` must not be collapsed to `try {} catch {}`
    // (ES2019) and optional chaining (ES2020) must not appear.
    const mainLegacyChunk = findAssetFile(/chunk-main-legacy/)
    expect(mainLegacyChunk).toMatch(/catch\s*\(/)
    expect(mainLegacyChunk).not.toMatch(/catch\s*\{/)
    expect(mainLegacyChunk).not.toMatch(/\w\?\.\w/)
  })

  test('should emit css file', async () => {
    expect(
      listAssets().some((filename) => filename.endsWith('.css')),
    ).toBeTruthy()
  })

  test('includes structuredClone polyfill which is supported after core-js v3', () => {
    expect(findAssetFile(/polyfills-legacy/)).toMatch('`structuredClone`')
    expect(findAssetFile(/polyfills-[-\w]{8}\./)).toMatch('`structuredClone`')
  })

  test('should generate legacy sourcemap file', async () => {
    expect(
      listAssets().some((filename) =>
        /chunk-main-legacy\.[-\w]{8}\.js\.map$/.test(filename),
      ),
    ).toBeTruthy()
    expect(
      listAssets().some((filename) =>
        /polyfills-legacy-[-\w]{8}\.js\.map$/.test(filename),
      ),
    ).toBeTruthy()
    // also for modern polyfills
    expect(
      listAssets().some((filename) =>
        /polyfills-[-\w]{8}\.js\.map$/.test(filename),
      ),
    ).toBeTruthy()
  })

  test('should have only modern entry files guarded', async () => {
    const guard = /(import\s*\()|(import.meta)|(async\s*function\*)/
    expect(findAssetFile(/index(?!-legacy)/)).toMatch(guard)
    expect(findAssetFile(/polyfills(?!-legacy)/)).toMatch(guard)

    expect(findAssetFile(/chunk-async(?!-legacy)/)).not.toMatch(guard)
    expect(findAssetFile(/index-legacy/)).not.toMatch(guard)
  })

  test('should not include preload helper in legacy chunks', async () => {
    expect(
      listAssets().filter(
        (filename) =>
          filename.includes('-legacy') &&
          readFile(`dist/assets/${filename}`).includes('Unable to preload'),
      ),
    ).toStrictEqual([])
  })
})


//===- FuzzerDriver.cpp - FuzzerDriver function and flags -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// FuzzerDriver and flag parsing.
//===----------------------------------------------------------------------===//

#include "FuzzerCorpus.h"
#include "FuzzerInterface.h"
#include "FuzzerInternal.h"
#include "FuzzerIO.h"
#include "FuzzerMutate.h"
#include "FuzzerRandom.h"
#include "FuzzerTracePC.h"
#include <algorithm>
#include <atomic>
#include <chrono>
#include <cstring>
#include <mutex>
#include <string>
#include <thread>

// This function should be present in the libFuzzer so that the client
// binary can test for its existence.
extern "C" __attribute__((used)) void __libfuzzer_is_present() {}

namespace fuzzer {

// Program arguments.
struct FlagDescription {
  const char *Name;
  const char *Description;
  int   Default;
  int   *IntFlag;
  const char **StrFlag;
  unsigned int *UIntFlag;
};

struct {
#define FUZZER_DEPRECATED_FLAG(Name)
#define FUZZER_FLAG_INT(Name, Default, Description) int Name;
#define FUZZER_FLAG_UNSIGNED(Name, Default, Description) unsigned int Name;
#define FUZZER_FLAG_STRING(Name, Description) const char *Name;
#include "FuzzerFlags.def"
#undef FUZZER_DEPRECATED_FLAG
#undef FUZZER_FLAG_INT
#undef FUZZER_FLAG_UNSIGNED
#undef FUZZER_FLAG_STRING
} Flags;

static const FlagDescription FlagDescriptions [] {
#define FUZZER_DEPRECATED_FLAG(Name)                                           \
  {#Name, "Deprecated; don't use", 0, nullptr, nullptr, nullptr},
#define FUZZER_FLAG_INT(Name, Default, Description)                            \
  {#Name, Description, Default, &Flags.Name, nullptr, nullptr},
#define FUZZER_FLAG_UNSIGNED(Name, Default, Description)                       \
  {#Name,   Description, static_cast<int>(Default),                            \
   nullptr, nullptr, &Flags.Name},
#define FUZZER_FLAG_STRING(Name, Description)                                  \
  {#Name, Description, 0, nullptr, &Flags.Name, nullptr},
#include "FuzzerFlags.def"
#undef FUZZER_DEPRECATED_FLAG
#undef FUZZER_FLAG_INT
#undef FUZZER_FLAG_UNSIGNED
#undef FUZZER_FLAG_STRING
};

static const size_t kNumFlags =
    sizeof(FlagDescriptions) / sizeof(FlagDescriptions[0]);

static std::vector<std::string> *Inputs;
static std::string *ProgName;

static void PrintHelp() {
  Printf("Usage:\n");
  auto Prog = ProgName->c_str();
  Printf("\nTo run fuzzing pass 0 or more directories.\n");
  Printf("%s [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ]\n", Prog);

  Printf("\nTo run individual tests without fuzzing pass 1 or more files:\n");
  Printf("%s [-flag1=val1 [-flag2=val2 ...] ] file1 [file2 ...]\n", Prog);

  Printf("\nFlags: (strictly in form -flag=value)\n");
  size_t MaxFlagLen = 0;
  for (size_t F = 0; F < kNumFlags; F++)
    MaxFlagLen = std::max(strlen(FlagDescriptions[F].Name), MaxFlagLen);

  for (size_t F = 0; F < kNumFlags; F++) {
    const auto &D = FlagDescriptions[F];
    if (strstr(D.Description, "internal flag") == D.Description) continue;
    Printf(" %s", D.Name);
    for (size_t i = 0, n = MaxFlagLen - strlen(D.Name); i < n; i++)
      Printf(" ");
    Printf("\t");
    Printf("%d\t%s\n", D.Default, D.Description);
  }
  Printf("\nFlags starting with '--' will be ignored and "
            "will be passed verbatim to subprocesses.\n");
}

static const char *FlagValue(const char *Param, const char *Name) {
  size_t Len = strlen(Name);
  if (Param[0] == '-' && strstr(Param + 1, Name) == Param + 1 &&
      Param[Len + 1] == '=')
      return &Param[Len + 2];
  return nullptr;
}

// Avoid calling stol as it triggers a bug in clang/glibc build.
static long MyStol(const char *Str) {
  long Res = 0;
  long Sign = 1;
  if (*Str == '-') {
    Str++;
    Sign = -1;
  }
  for (size_t i = 0; Str[i]; i++) {
    char Ch = Str[i];
    if (Ch < '0' || Ch > '9')
      return Res;
    Res = Res * 10 + (Ch - '0');
  }
  return Res * Sign;
}

static bool ParseOneFlag(const char *Param) {
  if (Param[0] != '-') return false;
  if (Param[1] == '-') {
    static bool PrintedWarning = false;
    if (!PrintedWarning) {
      PrintedWarning = true;
      Printf("INFO: libFuzzer ignores flags that start with '--'\n");
    }
    for (size_t F = 0; F < kNumFlags; F++)
      if (FlagValue(Param + 1, FlagDescriptions[F].Name))
        Printf("WARNING: did you mean '%s' (single dash)?\n", Param + 1);
    return true;
  }
  for (size_t F = 0; F < kNumFlags; F++) {
    const char *Name = FlagDescriptions[F].Name;
    const char *Str = FlagValue(Param, Name);
    if (Str)  {
      if (FlagDescriptions[F].IntFlag) {
        int Val = MyStol(Str);
        *FlagDescriptions[F].IntFlag = Val;
        if (Flags.verbosity >= 2)
          Printf("Flag: %s %d\n", Name, Val);
        return true;
      } else if (FlagDescriptions[F].UIntFlag) {
        unsigned int Val = std::stoul(Str);
        *FlagDescriptions[F].UIntFlag = Val;
        if (Flags.verbosity >= 2)
          Printf("Flag: %s %u\n", Name, Val);
        return true;
      } else if (FlagDescriptions[F].StrFlag) {
        *FlagDescriptions[F].StrFlag = Str;
        if (Flags.verbosity >= 2)
          Printf("Flag: %s %s\n", Name, Str);
        return true;
      } else {  // Deprecated flag.
        Printf("Flag: %s: deprecated, don't use\n", Name);
        return true;
      }
    }
  }
  Printf("\n\nWARNING: unrecognized flag '%s'; "
         "use -help=1 to list all flags\n\n", Param);
  return true;
}

// We don't use any library to minimize dependencies.
static void ParseFlags(const std::vector<std::string> &Args) {
  for (size_t F = 0; F < kNumFlags; F++) {
    if (FlagDescriptions[F].IntFlag)
      *FlagDescriptions[F].IntFlag = FlagDescriptions[F].Default;
    if (FlagDescriptions[F].UIntFlag)
      *FlagDescriptions[F].UIntFlag =
          static_cast<unsigned int>(FlagDescriptions[F].Default);
    if (FlagDescriptions[F].StrFlag)
      *FlagDescriptions[F].StrFlag = nullptr;
  }
  Inputs = new std::vector<std::string>;
  for (size_t A = 1; A < Args.size(); A++) {
    if (ParseOneFlag(Args[A].c_str())) continue;
    Inputs->push_back(Args[A]);
  }
}

static std::mutex Mu;

static void PulseThread() {
  while (true) {
    SleepSeconds(600);
    std::lock_guard<std::mutex> Lock(Mu);
    Printf("pulse...\n");
  }
}

static void WorkerThread(const std::string &Cmd, std::atomic<unsigned> *Counter,
                         unsigned NumJobs, std::atomic<bool> *HasErrors) {
  while (true) {
    unsigned C = (*Counter)++;
    if (C >= NumJobs) break;
    std::string Log = "fuzz-" + std::to_string(C) + ".log";
    std::string ToRun = Cmd + " > " + Log + " 2>&1\n";
    if (Flags.verbosity)
      Printf("%s", ToRun.c_str());
    int ExitCode = ExecuteCommand(ToRun);
    if (ExitCode != 0)
      *HasErrors = true;
    std::lock_guard<std::mutex> Lock(Mu);
    Printf("================== Job %u exited with exit code %d ============\n",
           C, ExitCode);
    fuzzer::CopyFileToErr(Log);
  }
}

std::string CloneArgsWithoutX(const std::vector<std::string> &Args,
                              const char *X1, const char *X2) {
  std::string Cmd;
  for (auto &S : Args) {
    if (FlagValue(S.c_str(), X1) || FlagValue(S.c_str(), X2))
      continue;
    Cmd += S + " ";
  }
  return Cmd;
}

static int RunInMultipleProcesses(const std::vector<std::string> &Args,
                                  unsigned NumWorkers, unsigned NumJobs) {
  std::atomic<unsigned> Counter(0);
  std::atomic<bool> HasErrors(false);
  std::string Cmd = CloneArgsWithoutX(Args, "jobs", "workers");
  std::vector<std::thread> V;
  std::thread Pulse(PulseThread);
  Pulse.detach();
  for (unsigned i = 0; i < NumWorkers; i++)
    V.push_back(std::thread(WorkerThread, Cmd, &Counter, NumJobs, &HasErrors));
  for (auto &T : V)
    T.join();
  return HasErrors ? 1 : 0;
}

static void RssThread(Fuzzer *F, size_t RssLimitMb) {
  while (true) {
    SleepSeconds(1);
    size_t Peak = GetPeakRSSMb();
    if (Peak > RssLimitMb)
      F->RssLimitCallback();
  }
}

static void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
  if (!RssLimitMb) return;
  std::thread T(RssThread, F, RssLimitMb);
  T.detach();
}

int RunOneTest(Fuzzer *F, const char *InputFilePath, size_t MaxLen) {
  Unit U = FileToVector(InputFilePath);
  if (MaxLen && MaxLen < U.size())
    U.resize(MaxLen);
  F->RunOne(U.data(), U.size());
  F->TryDetectingAMemoryLeak(U.data(), U.size(), true);
  return 0;
}

static bool AllInputsAreFiles() {
  if (Inputs->empty()) return false;
  for (auto &Path : *Inputs)
    if (!IsFile(Path))
      return false;
  return true;
}

int MinimizeCrashInput(const std::vector<std::string> &Args) {
  if (Inputs->size() != 1) {
    Printf("ERROR: -minimize_crash should be given one input file\n");
    exit(1);
  }
  std::string InputFilePath = Inputs->at(0);
  std::string BaseCmd =
      CloneArgsWithoutX(Args, "minimize_crash", "exact_artifact_path");
  auto InputPos = BaseCmd.find(" " + InputFilePath + " ");
  assert(InputPos != std::string::npos);
  BaseCmd.erase(InputPos, InputFilePath.size() + 1);
  if (Flags.runs <= 0 && Flags.max_total_time == 0) {
    Printf("INFO: you need to specify -runs=N or "
           "-max_total_time=N with -minimize_crash=1\n"
           "INFO: defaulting to -max_total_time=600\n");
    BaseCmd += " -max_total_time=600";
  }
  // BaseCmd += " >  /dev/null 2>&1 ";

  std::string CurrentFilePath = InputFilePath;
  while (true) {
    Unit U = FileToVector(CurrentFilePath);
    if (U.size() < 2) {
      Printf("CRASH_MIN: '%s' is small enough\n", CurrentFilePath.c_str());
      return 0;
    }
    Printf("CRASH_MIN: minimizing crash input: '%s' (%zd bytes)\n",
           CurrentFilePath.c_str(), U.size());

    auto Cmd = BaseCmd + " " + CurrentFilePath;

    Printf("CRASH_MIN: executing: %s\n", Cmd.c_str());
    int ExitCode = ExecuteCommand(Cmd);
    if (ExitCode == 0) {
      Printf("ERROR: the input %s did not crash\n", CurrentFilePath.c_str());
      exit(1);
    }
    Printf("CRASH_MIN: '%s' (%zd bytes) caused a crash. Will try to minimize "
           "it further\n",
           CurrentFilePath.c_str(), U.size());

    std::string ArtifactPath = "minimized-from-" + Hash(U);
    Cmd += " -minimize_crash_internal_step=1 -exact_artifact_path=" +
        ArtifactPath;
    Printf("CRASH_MIN: executing: %s\n", Cmd.c_str());
    ExitCode = ExecuteCommand(Cmd);
    if (ExitCode == 0) {
      if (Flags.exact_artifact_path) {
        CurrentFilePath = Flags.exact_artifact_path;
        WriteToFile(U, CurrentFilePath);
      }
      Printf("CRASH_MIN: failed to minimize beyond %s (%d bytes), exiting\n",
             CurrentFilePath.c_str(), U.size());
      return 0;
    }
    CurrentFilePath = ArtifactPath;
    Printf("\n\n\n\n\n\n*********************************\n");
  }
  return 0;
}

int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {
  assert(Inputs->size() == 1);
  std::string InputFilePath = Inputs->at(0);
  Unit U = FileToVector(InputFilePath);
  assert(U.size() > 2);
  Printf("INFO: Starting MinimizeCrashInputInternalStep: %zd\n", U.size());
  Corpus->AddToCorpus(U, 0);
  F->SetMaxInputLen(U.size());
  F->SetMaxMutationLen(U.size() - 1);
  F->MinimizeCrashLoop(U);
  Printf("INFO: Done MinimizeCrashInputInternalStep, no crashes found\n");
  exit(0);
  return 0;
}

int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
  using namespace fuzzer;
  assert(argc && argv && "Argument pointers cannot be nullptr");
  EF = new ExternalFunctions();
  if (EF->LLVMFuzzerInitialize)
    EF->LLVMFuzzerInitialize(argc, argv);
  const std::vector<std::string> Args(*argv, *argv + *argc);
  assert(!Args.empty());
  ProgName = new std::string(Args[0]);
  ParseFlags(Args);
  if (Flags.help) {
    PrintHelp();
    return 0;
  }

  if (Flags.minimize_crash)
    return MinimizeCrashInput(Args);

  if (Flags.close_fd_mask & 2)
    DupAndCloseStderr();
  if (Flags.close_fd_mask & 1)
    CloseStdout();

  if (Flags.jobs > 0 && Flags.workers == 0) {
    Flags.workers = std::min(NumberOfCpuCores() / 2, Flags.jobs);
    if (Flags.workers > 1)
      Printf("Running %u workers\n", Flags.workers);
  }

  if (Flags.workers > 0 && Flags.jobs > 0)
    return RunInMultipleProcesses(Args, Flags.workers, Flags.jobs);

  const size_t kMaxSaneLen = 1 << 20;
  const size_t kMinDefaultLen = 64;
  FuzzingOptions Options;
  Options.Verbosity = Flags.verbosity;
  Options.MaxLen = Flags.max_len;
  Options.UnitTimeoutSec = Flags.timeout;
  Options.ErrorExitCode = Flags.error_exitcode;
  Options.TimeoutExitCode = Flags.timeout_exitcode;
  Options.MaxTotalTimeSec = Flags.max_total_time;
  Options.DoCrossOver = Flags.cross_over;
  Options.MutateDepth = Flags.mutate_depth;
  Options.UseCounters = Flags.use_counters;
  Options.UseIndirCalls = Flags.use_indir_calls;
  Options.UseMemcmp = Flags.use_memcmp;
  Options.UseMemmem = Flags.use_memmem;
  Options.UseCmp = Flags.use_cmp;
  Options.UseValueProfile = Flags.use_value_profile;
  Options.Shrink = Flags.shrink;
  Options.ShuffleAtStartUp = Flags.shuffle;
  Options.PreferSmall = Flags.prefer_small;
  Options.ReloadIntervalSec = Flags.reload;
  Options.OnlyASCII = Flags.only_ascii;
  Options.OutputCSV = Flags.output_csv;
  Options.DetectLeaks = Flags.detect_leaks;
  Options.TraceMalloc = Flags.trace_malloc;
  Options.RssLimitMb = Flags.rss_limit_mb;
  if (Flags.runs >= 0)
    Options.MaxNumberOfRuns = Flags.runs;
  if (!Inputs->empty() && !Flags.minimize_crash_internal_step)
    Options.OutputCorpus = (*Inputs)[0];
  Options.ReportSlowUnits = Flags.report_slow_units;
  if (Flags.artifact_prefix)
    Options.ArtifactPrefix = Flags.artifact_prefix;
  if (Flags.exact_artifact_path)
    Options.ExactArtifactPath = Flags.exact_artifact_path;
  std::vector<Unit> Dictionary;
  if (Flags.dict)
    if (!ParseDictionaryFile(FileToString(Flags.dict), &Dictionary))
      return 1;
  if (Flags.verbosity > 0 && !Dictionary.empty())
    Printf("Dictionary: %zd entries\n", Dictionary.size());
  bool DoPlainRun = AllInputsAreFiles();
  Options.SaveArtifacts =
      !DoPlainRun || Flags.minimize_crash_internal_step;
  Options.PrintNewCovPcs = Flags.print_pcs;
  Options.PrintFinalStats = Flags.print_final_stats;
  Options.PrintCorpusStats = Flags.print_corpus_stats;
  Options.PrintCoverage = Flags.print_coverage;
  Options.DumpCoverage = Flags.dump_coverage;
  if (Flags.exit_on_src_pos)
    Options.ExitOnSrcPos = Flags.exit_on_src_pos;
  if (Flags.exit_on_item)
    Options.ExitOnItem = Flags.exit_on_item;

  unsigned Seed = Flags.seed;
  // Initialize Seed.
  if (Seed == 0)
    Seed = (std::chrono::system_clock::now().time_since_epoch().count() << 10) +
           GetPid();
  if (Flags.verbosity)
    Printf("INFO: Seed: %u\n", Seed);

  Random Rand(Seed);
  auto *MD = new MutationDispatcher(Rand, Options);
  auto *Corpus = new InputCorpus(Options.OutputCorpus);
  auto *F = new Fuzzer(Callback, *Corpus, *MD, Options);

  for (auto &U: Dictionary)
    if (U.size() <= Word::GetMaxSize())
      MD->AddWordToManualDictionary(Word(U.data(), U.size()));

  StartRssThread(F, Flags.rss_limit_mb);

  Options.HandleAbrt = Flags.handle_abrt;
  Options.HandleBus = Flags.handle_bus;
  Options.HandleFpe = Flags.handle_fpe;
  Options.HandleIll = Flags.handle_ill;
  Options.HandleInt = Flags.handle_int;
  Options.HandleSegv = Flags.handle_segv;
  Options.HandleTerm = Flags.handle_term;
  SetSignalHandler(Options);

  if (Flags.minimize_crash_internal_step)
    return MinimizeCrashInputInternalStep(F, Corpus);

  if (DoPlainRun) {
    Options.SaveArtifacts = false;
    int Runs = std::max(1, Flags.runs);
    Printf("%s: Running %zd inputs %d time(s) each.\n", ProgName->c_str(),
           Inputs->size(), Runs);
    for (auto &Path : *Inputs) {
      auto StartTime = system_clock::now();
      Printf("Running: %s\n", Path.c_str());
      for (int Iter = 0; Iter < Runs; Iter++)
        RunOneTest(F, Path.c_str(), Options.MaxLen);
      auto StopTime = system_clock::now();
      auto MS = duration_cast<milliseconds>(StopTime - StartTime).count();
      Printf("Executed %s in %zd ms\n", Path.c_str(), (long)MS);
    }
    Printf("***\n"
           "*** NOTE: fuzzing was not performed, you have only\n"
           "***       executed the target code on a fixed set of inputs.\n"
           "***\n");
    F->PrintFinalStats();
    exit(0);
  }

  if (Flags.merge) {
    if (Options.MaxLen == 0)
      F->SetMaxInputLen(kMaxSaneLen);
    if (TPC.UsingTracePcGuard()) {
      if (Flags.merge_control_file)
        F->CrashResistantMergeInternalStep(Flags.merge_control_file);
      else
        F->CrashResistantMerge(Args, *Inputs);
    } else {
      F->Merge(*Inputs);
    }
    exit(0);
  }

  size_t TemporaryMaxLen = Options.MaxLen ? Options.MaxLen : kMaxSaneLen;

  UnitVector InitialCorpus;
  for (auto &Inp : *Inputs) {
    Printf("Loading corpus dir: %s\n", Inp.c_str());
    ReadDirToVectorOfUnits(Inp.c_str(), &InitialCorpus, nullptr,
                           TemporaryMaxLen, /*ExitOnError=*/false);
  }

  if (Options.MaxLen == 0) {
    size_t MaxLen = 0;
    for (auto &U : InitialCorpus)
      MaxLen = std::max(U.size(), MaxLen);
    F->SetMaxInputLen(std::min(std::max(kMinDefaultLen, MaxLen), kMaxSaneLen));
  }

  if (InitialCorpus.empty()) {
    InitialCorpus.push_back(Unit({'\n'}));  // Valid ASCII input.
    if (Options.Verbosity)
      Printf("INFO: A corpus is not provided, starting from an empty corpus\n");
  }
  F->ShuffleAndMinimize(&InitialCorpus);
  InitialCorpus.clear();  // Don't need this memory any more.
  F->Loop();

  if (Flags.verbosity)
    Printf("Done %d runs in %zd second(s)\n", F->getTotalNumberOfRuns(),
           F->secondsSinceProcessStartUp());
  F->PrintFinalStats();

  exit(0);  // Don't let F destroy itself.
}

// Storage for global ExternalFunctions object.
ExternalFunctions *EF = nullptr;

}  // namespace fuzzer


//     __ _____ _____ _____
//  __|  |   __|     |   | |  JSON for Modern C++
// |  |  |__   |  |  | | | |  version 3.12.0
// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT

#pragma once

#include <cstddef> // size_t
#include <iterator> // forward_iterator_tag
#include <tuple> // tuple_size, get, tuple_element
#include <utility> // move

#if JSON_HAS_RANGES
    #include <ranges> // enable_borrowed_range
#endif

#include <nlohmann/detail/abi_macros.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/string_utils.hpp>
#include <nlohmann/detail/value_t.hpp>

NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{

template<typename IteratorType> class iteration_proxy_value
{
  public:
    using difference_type = std::ptrdiff_t;
    using value_type = iteration_proxy_value;
    using pointer = value_type *;
    using reference = value_type &;
    using iterator_category = std::forward_iterator_tag;
    using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;

  private:
    /// the iterator
    IteratorType anchor{};
    /// an index for arrays (used to create key names)
    std::size_t array_index = 0;
    /// last stringified array index
    mutable std::size_t array_index_last = 0;
    /// a string representation of the array index
    mutable string_type array_index_str = "0";
    /// an empty string (to return a reference for primitive values)
    string_type empty_str{};

  public:
    explicit iteration_proxy_value() = default;
    explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
    noexcept(std::is_nothrow_move_constructible<IteratorType>::value
             && std::is_nothrow_default_constructible<string_type>::value)
        : anchor(std::move(it))
        , array_index(array_index_)
    {}

    iteration_proxy_value(iteration_proxy_value const&) = default;
    iteration_proxy_value& operator=(iteration_proxy_value const&) = default;
    // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
    iteration_proxy_value(iteration_proxy_value&&)
    noexcept(std::is_nothrow_move_constructible<IteratorType>::value
             && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
    iteration_proxy_value& operator=(iteration_proxy_value&&)
    noexcept(std::is_nothrow_move_assignable<IteratorType>::value
             && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
    ~iteration_proxy_value() = default;

    /// dereference operator (needed for range-based for)
    const iteration_proxy_value& operator*() const
    {
        return *this;
    }

    /// increment operator (needed for range-based for)
    iteration_proxy_value& operator++()
    {
        ++anchor;
        ++array_index;

        return *this;
    }

    iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
    {
        auto tmp = iteration_proxy_value(anchor, array_index);
        ++anchor;
        ++array_index;
        return tmp;
    }

    /// equality operator (needed for InputIterator)
    bool operator==(const iteration_proxy_value& o) const
    {
        return anchor == o.anchor;
    }

    /// inequality operator (needed for range-based for)
    bool operator!=(const iteration_proxy_value& o) const
    {
        return anchor != o.anchor;
    }

    /// return key of the iterator
    const string_type& key() const
    {
        JSON_ASSERT(anchor.m_object != nullptr);

        switch (anchor.m_object->type())
        {
            // use integer array index as key
            case value_t::array:
            {
                if (array_index != array_index_last)
                {
                    int_to_string( array_index_str, array_index );
                    array_index_last = array_index;
                }
                return array_index_str;
            }

            // use key from the object
            case value_t::object:
                return anchor.key();

            // use an empty key for all primitive types
            case value_t::null:
            case value_t::string:
            case value_t::boolean:
            case value_t::number_integer:
            case value_t::number_unsigned:
            case value_t::number_float:
            case value_t::binary:
            case value_t::discarded:
            default:
                return empty_str;
        }
    }

    /// return value of the iterator
    typename IteratorType::reference value() const
    {
        return anchor.value();
    }
};

/// proxy class for the items() function
template<typename IteratorType> class iteration_proxy
{
  private:
    /// the container to iterate
    typename IteratorType::pointer container = nullptr;

  public:
    explicit iteration_proxy() = default;

    /// construct iteration proxy from a container
    explicit iteration_proxy(typename IteratorType::reference cont) noexcept
        : container(&cont) {}

    iteration_proxy(iteration_proxy const&) = default;
    iteration_proxy& operator=(iteration_proxy const&) = default;
    iteration_proxy(iteration_proxy&&) noexcept = default;
    iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
    ~iteration_proxy() = default;

    /// return iterator begin (needed for range-based for)
    iteration_proxy_value<IteratorType> begin() const noexcept
    {
        return iteration_proxy_value<IteratorType>(container->begin());
    }

    /// return iterator end (needed for range-based for)
    iteration_proxy_value<IteratorType> end() const noexcept
    {
        return iteration_proxy_value<IteratorType>(container->end());
    }
};

// Structured Bindings Support
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
// And see https://github.com/nlohmann/json/pull/1391
template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
{
    return i.key();
}
// Structured Bindings Support
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
// And see https://github.com/nlohmann/json/pull/1391
template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
{
    return i.value();
}

}  // namespace detail
NLOHMANN_JSON_NAMESPACE_END

// The Addition to the STD Namespace is required to add
// Structured Bindings Support to the iteration_proxy_value class
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
// And see https://github.com/nlohmann/json/pull/1391
namespace std
{

#if defined(__clang__)
    // Fix: https://github.com/nlohmann/json/issues/1401
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wmismatched-tags"
#endif
template<typename IteratorType>
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
    : public std::integral_constant<std::size_t, 2> {};

template<std::size_t N, typename IteratorType>
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
{
  public:
    using type = decltype(
                     get<N>(std::declval <
                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
};
#if defined(__clang__)
    #pragma clang diagnostic pop
#endif

}  // namespace std

#if JSON_HAS_RANGES
    template <typename IteratorType>
    inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
#endif


#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main()
{
    // create a JSON array
    json j1 = {"one", "two", 3, 4.5, false};

    // create a copy
    json j2(j1);

    // serialize the JSON array
    std::cout << j1 << " = " << j2 << '\n';
    std::cout << std::boolalpha << (j1 == j2) << '\n';
}


//===- FuzzerCrossOver.cpp - Cross over two test inputs -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Cross over test inputs.
//===----------------------------------------------------------------------===//

#include "FuzzerDefs.h"
#include "FuzzerMutate.h"
#include "FuzzerRandom.h"
#include <cstring>

namespace fuzzer {

// Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out.
size_t MutationDispatcher::CrossOver(const uint8_t *Data1, size_t Size1,
                                     const uint8_t *Data2, size_t Size2,
                                     uint8_t *Out, size_t MaxOutSize) {
  assert(Size1 || Size2);
  MaxOutSize = Rand(MaxOutSize) + 1;
  size_t OutPos = 0;
  size_t Pos1 = 0;
  size_t Pos2 = 0;
  size_t *InPos = &Pos1;
  size_t InSize = Size1;
  const uint8_t *Data = Data1;
  bool CurrentlyUsingFirstData = true;
  while (OutPos < MaxOutSize && (Pos1 < Size1 || Pos2 < Size2)) {
    // Merge a part of Data into Out.
    size_t OutSizeLeft = MaxOutSize - OutPos;
    if (*InPos < InSize) {
      size_t InSizeLeft = InSize - *InPos;
      size_t MaxExtraSize = std::min(OutSizeLeft, InSizeLeft);
      size_t ExtraSize = Rand(MaxExtraSize) + 1;
      memcpy(Out + OutPos, Data + *InPos, ExtraSize);
      OutPos += ExtraSize;
      (*InPos) += ExtraSize;
    }
    // Use the other input data on the next iteration.
    InPos  = CurrentlyUsingFirstData ? &Pos2 : &Pos1;
    InSize = CurrentlyUsingFirstData ? Size2 : Size1;
    Data   = CurrentlyUsingFirstData ? Data2 : Data1;
    CurrentlyUsingFirstData = !CurrentlyUsingFirstData;
  }
  return OutPos;
}

}  // namespace fuzzer


#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main()
{
    // create JSON values
    json j_null;
    json j_boolean = true;
    json j_number_integer = -17;
    json j_number_unsigned = 42u;
    json j_number_float = 23.42;
    json j_object = {{"one", 1}, {"two", 2}};
    json j_array = {1, 2, 4, 8, 16};
    json j_string = "Hello, world";

    // call operator value_t()
    json::value_t t_null = j_null;
    json::value_t t_boolean = j_boolean;
    json::value_t t_number_integer = j_number_integer;
    json::value_t t_number_unsigned = j_number_unsigned;
    json::value_t t_number_float = j_number_float;
    json::value_t t_object = j_object;
    json::value_t t_array = j_array;
    json::value_t t_string = j_string;

    // print types
    std::cout << std::boolalpha;
    std::cout << (t_null == json::value_t::null) << '\n';
    std::cout << (t_boolean == json::value_t::boolean) << '\n';
    std::cout << (t_number_integer == json::value_t::number_integer) << '\n';
    std::cout << (t_number_unsigned == json::value_t::number_unsigned) << '\n';
    std::cout << (t_number_float == json::value_t::number_float) << '\n';
    std::cout << (t_object == json::value_t::object) << '\n';
    std::cout << (t_array == json::value_t::array) << '\n';
    std::cout << (t_string == json::value_t::string) << '\n';
}


//===- FuzzerMain.cpp - main() function and flags -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// main() and flags.
//===----------------------------------------------------------------------===//

#include "FuzzerDefs.h"

extern "C" {
// This function should be defined by the user.
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
}  // extern "C"

int main(int argc, char **argv) {
  return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
}


#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main()
{
    // create JSON values
    json array = {1, 2, 3, 4, 5};
    json null;

    // print values
    std::cout << array << '\n';
    std::cout << null << '\n';

    // add values
    array.push_back(6);
    array += 7;
    null += "first";
    null += "second";

    // print values
    std::cout << array << '\n';
    std::cout << null << '\n';
}


// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

// Simple test for a fuzzer. The fuzzer must find the string "FUZZ".
#include <cstdint>
#include <cstdlib>
#include <cstddef>
#include <iostream>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  int bits = 0;
  if (Size > 0 && Data[0] == 'F') bits |= 1;
  if (Size > 1 && Data[1] == 'U') bits |= 2;
  if (Size > 2 && Data[2] == 'Z') bits |= 4;
  if (Size > 3 && Data[3] == 'Z') bits |= 8;
  if (bits == 15) {
    std::cerr <<  "BINGO!\n";
    exit(1);
  }
  return 0;
}


// run when format es
import NestedWorker from '../emit-chunk-nested-worker?worker'
import ImportMetaGlobWorker from '../importMetaGlob.worker?worker'

function text(el, text) {
  document.querySelector(el).textContent = text
}

text('.format-es', 'format es:')

const nestedWorker = new NestedWorker()
const dataList = []
nestedWorker.addEventListener('message', (ev) => {
  dataList.push(ev.data)
  text(
    '.emit-chunk-worker',
    JSON.stringify(
      dataList.sort(
        (a, b) => JSON.stringify(a).length - JSON.stringify(b).length,
      ),
    ),
  )
})

const dynamicImportWorker = new Worker(
  new URL('../emit-chunk-dynamic-import-worker.js', import.meta.url),
  {
    type: 'module',
  },
)
dynamicImportWorker.addEventListener('message', (ev) => {
  text('.emit-chunk-dynamic-import-worker', JSON.stringify(ev.data))
})

const moduleWorker = new Worker(
  new URL('../module-and-worker.js', import.meta.url),
  { type: 'module' },
)

moduleWorker.addEventListener('message', (ev) => {
  text('.module-and-worker-worker', JSON.stringify(ev.data))
})

const importMetaGlobWorker = new ImportMetaGlobWorker()

importMetaGlobWorker.postMessage('1')

importMetaGlobWorker.addEventListener('message', (e) => {
  text('.importMetaGlob-worker', JSON.stringify(e.data))
})


//===- FuzzerTracePC.h - Internal header for the Fuzzer ---------*- C++ -* ===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// fuzzer::TracePC
//===----------------------------------------------------------------------===//

#ifndef LLVM_FUZZER_TRACE_PC
#define LLVM_FUZZER_TRACE_PC

#include "FuzzerDefs.h"
#include "FuzzerValueBitMap.h"
#include <set>

namespace fuzzer {

// TableOfRecentCompares (TORC) remembers the most recently performed
// comparisons of type T.
// We record the arguments of CMP instructions in this table unconditionally
// because it seems cheaper this way than to compute some expensive
// conditions inside __sanitizer_cov_trace_cmp*.
// After the unit has been executed we may decide to use the contents of
// this table to populate a Dictionary.
template<class T, size_t kSizeT>
struct TableOfRecentCompares {
  static const size_t kSize = kSizeT;
  struct Pair {
    T A, B;
  };
  void Insert(size_t Idx, T Arg1, T Arg2) {
    Idx = Idx % kSize;
    Table[Idx].A = Arg1;
    Table[Idx].B = Arg2;
  }

  Pair Get(size_t I) { return Table[I % kSize]; }

  Pair Table[kSize];
};

class TracePC {
 public:
  static const size_t kFeatureSetSize = ValueBitMap::kNumberOfItems;

  void HandleTrace(uint32_t *guard, uintptr_t PC);
  void HandleInit(uint32_t *start, uint32_t *stop);
  void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
  void HandleValueProfile(size_t Value) { ValueProfileMap.AddValue(Value); }
  template <class T> void HandleCmp(void *PC, T Arg1, T Arg2);
  size_t GetTotalPCCoverage();
  void SetUseCounters(bool UC) { UseCounters = UC; }
  void SetUseValueProfile(bool VP) { UseValueProfile = VP; }
  void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; }
  template <class Callback> size_t CollectFeatures(Callback CB);
  bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) {
    return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap);
  }

  void ResetMaps() {
    ValueProfileMap.Reset();
    memset(Counters, 0, sizeof(Counters));
  }

  void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize);
  void PrintFeatureSet();

  void PrintModuleInfo();

  void PrintCoverage();
  void DumpCoverage();

  void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
                         size_t n);
  void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,
                         size_t n);

  bool UsingTracePcGuard() const {return NumModules; }

  static const size_t kTORCSize = 1 << 5;
  TableOfRecentCompares<uint32_t, kTORCSize> TORC4;
  TableOfRecentCompares<uint64_t, kTORCSize> TORC8;

  void PrintNewPCs();
  size_t GetNumPCs() const { return Min(kNumPCs, NumGuards + 1); }
  uintptr_t GetPC(size_t Idx) {
    assert(Idx < GetNumPCs());
    return PCs[Idx];
  }

private:
  bool UseCounters = false;
  bool UseValueProfile = false;
  bool DoPrintNewPCs = false;

  struct Module {
    uint32_t *Start, *Stop;
  };

  Module Modules[4096];
  size_t NumModules;  // linker-initialized.
  size_t NumGuards;  // linker-initialized.

  static const size_t kNumCounters = 1 << 14;
  alignas(8) uint8_t Counters[kNumCounters];

  static const size_t kNumPCs = 1 << 24;
  uintptr_t PCs[kNumPCs];

  std::set<uintptr_t> *PrintedPCs;

  ValueBitMap ValueProfileMap;
};

template <class Callback>
size_t TracePC::CollectFeatures(Callback CB) {
  if (!UsingTracePcGuard()) return 0;
  size_t Res = 0;
  const size_t Step = 8;
  assert(reinterpret_cast<uintptr_t>(Counters) % Step == 0);
  size_t N = Min(kNumCounters, NumGuards + 1);
  N = (N + Step - 1) & ~(Step - 1);  // Round up.
  for (size_t Idx = 0; Idx < N; Idx += Step) {
    uint64_t Bundle = *reinterpret_cast<uint64_t*>(&Counters[Idx]);
    if (!Bundle) continue;
    for (size_t i = Idx; i < Idx + Step; i++) {
      uint8_t Counter = (Bundle >> ((i - Idx) * 8)) & 0xff;
      if (!Counter) continue;
      Counters[i] = 0;
      unsigned Bit = 0;
      /**/ if (Counter >= 128) Bit = 7;
      else if (Counter >= 32) Bit = 6;
      else if (Counter >= 16) Bit = 5;
      else if (Counter >= 8) Bit = 4;
      else if (Counter >= 4) Bit = 3;
      else if (Counter >= 3) Bit = 2;
      else if (Counter >= 2) Bit = 1;
      size_t Feature = (i * 8 + Bit);
      if (CB(Feature))
        Res++;
    }
  }
  if (UseValueProfile)
    ValueProfileMap.ForEach([&](size_t Idx) {
      if (CB(NumGuards * 8 + Idx))
        Res++;
    });
  return Res;
}

extern TracePC TPC;

}  // namespace fuzzer

#endif  // LLVM_FUZZER_TRACE_PC


import { beforeAll, describe, expect, test } from 'vitest'
import {
  browserLogs,
  findAssetFile,
  getBg,
  getColor,
  isBuild,
  isBundled,
  isBundledDev,
  page,
} from '~utils'

// bundled dev serves hashed asset URLs like build. But it writes them to the
// default `assets/` folder, because build's custom assetFileNames setting
// (other-assets/) is not applied here.
const absoluteAssetMatch = isBuild
  ? /http.*\/other-assets\/asset-[-\w]{8}\.png/
  : isBundledDev
    ? /\/assets\/asset-[-\w]{8}\.png/
    : '/nested/asset.png'

// Asset URLs in CSS are relative to the same dir, the computed
// style returns the absolute URL in the test
const cssBgAssetMatch = absoluteAssetMatch

const iconMatch = `/icon.png`

const absoluteIconMatch = isBundled
  ? /http.*\/icon-[-\w]{8}\.png/
  : '/nested/icon.png'

const absolutePublicIconMatch = isBuild ? /http.*\/icon\.png/ : '/icon.png'

test('should have no 404s', () => {
  browserLogs.forEach((msg) => {
    expect(msg).not.toMatch('404')
  })
})

describe('raw references from /public', () => {
  test('load raw js from /public', async () => {
    expect(await page.textContent('.raw-js')).toMatch('[success]')
  })

  test('load raw css from /public', async () => {
    expect(await getColor('.raw-css')).toBe('red')
  })
})

test('import-expression from simple script', async () => {
  expect(await page.textContent('.import-expression')).toMatch(
    '[success][success]',
  )
})

describe('asset imports from js', () => {
  test('relative', async () => {
    expect(await page.textContent('.asset-import-relative')).toMatch(
      cssBgAssetMatch,
    )
  })

  test('absolute', async () => {
    expect(await page.textContent('.asset-import-absolute')).toMatch(
      cssBgAssetMatch,
    )
  })

  test('from /public', async () => {
    expect(await page.textContent('.public-import')).toMatch(
      absolutePublicIconMatch,
    )
  })
})

describe('css url() references', () => {
  test('fonts', async () => {
    expect(
      await page.evaluate(() => {
        return (document as any).fonts.check('700 32px Inter')
      }),
    ).toBe(true)
  })

  test('relative', async () => {
    const bg = await getBg('.css-url-relative')
    expect(bg).toMatch(cssBgAssetMatch)
  })

  test('image-set relative', async () => {
    const imageSet = await getBg('.css-image-set-relative')
    imageSet.split(', ').forEach((s) => {
      expect(s).toMatch(cssBgAssetMatch)
    })
  })

  test('image-set without the url() call', async () => {
    const imageSet = await getBg('.css-image-set-without-url-call')
    imageSet.split(', ').forEach((s) => {
      expect(s).toMatch(cssBgAssetMatch)
    })
  })

  test('image-set with var', async () => {
    const imageSet = await getBg('.css-image-set-with-var')
    imageSet.split(', ').forEach((s) => {
      expect(s).toMatch(cssBgAssetMatch)
    })
  })

  test('image-set with mix', async () => {
    const imageSet = await getBg('.css-image-set-mix-url-var')
    imageSet.split(', ').forEach((s) => {
      expect(s).toMatch(cssBgAssetMatch)
    })
  })

  test('relative in @import', async () => {
    expect(await getBg('.css-url-relative-at-imported')).toMatch(
      cssBgAssetMatch,
    )
  })

  test('absolute', async () => {
    expect(await getBg('.css-url-absolute')).toMatch(cssBgAssetMatch)
  })

  test('from /public', async () => {
    expect(await getBg('.css-url-public')).toMatch(iconMatch)
  })

  test('multiple urls on the same line', async () => {
    const bg = await getBg('.css-url-same-line')
    expect(bg).toMatch(cssBgAssetMatch)
    expect(bg).toMatch(iconMatch)
  })

  test('aliased', async () => {
    const bg = await getBg('.css-url-aliased')
    expect(bg).toMatch(cssBgAssetMatch)
  })

  test('nested manual chunks', async () => {
    const bg = await getBg('.css-manual-chunks-relative')
    expect(bg).toMatch(cssBgAssetMatch)
  })
})

describe.runIf(isBuild)('index.css URLs', () => {
  let css: string
  beforeAll(() => {
    css = findAssetFile(/index.*\.css$/, 'relative-base', 'other-assets')
  })

  test('relative asset URL', () => {
    expect(css).toMatch(`./asset-`)
  })

  test('preserve postfix query/hash', () => {
    expect(css).toMatch(`woff2?#iefix`)
  })
})

describe('image', () => {
  test('srcset', async () => {
    const img = await page.$('.img-src-set')
    const srcset = await img.getAttribute('srcset')
    srcset.split(', ').forEach((s) => {
      expect(s).toMatch(
        isBuild
          ? /other-assets\/asset-[-\w]{8}\.png \dx/
          : isBundledDev
            ? /\/assets\/asset-[-\w]{8}\.png \dx/
            : /\.\/nested\/asset\.png \dx/,
      )
    })
  })
})

describe('svg fragments', () => {
  // 404 is checked already, so here we just ensure the urls end with #fragment
  // bundled dev drops the #fragment postfix from hashed asset URLs (vitejs/vite#23028)
  test.skipIf(isBundledDev)('img url', async () => {
    const img = await page.$('.svg-frag-img')
    expect(await img.getAttribute('src')).toMatch(/svg#icon-clock-view$/)
  })

  // bundled dev: #fragment dropped (see 'img url')
  test.skipIf(isBundledDev)('via css url()', async () => {
    expect(await getBg('.icon')).toMatch(/svg#icon-clock-view"\)$/)
  })

  test('from js import', async () => {
    const img = await page.$('.svg-frag-import')
    expect(await img.getAttribute('src')).toMatch(/svg#icon-heart-view$/)
  })
})

test('?raw import', async () => {
  expect(await page.textContent('.raw')).toMatch('SVG')
})

test('?url import', async () => {
  expect(await page.textContent('.url')).toMatch(
    isBuild
      ? /http.*\/other-assets\/foo-[-\w]{8}\.js/
      : isBundledDev
        ? /\/assets\/foo-[-\w]{8}\.js/
        : `/foo.js`,
  )
})

test('?url import on css', async () => {
  const txt = await page.textContent('.url-css')
  expect(txt).toMatch(
    isBuild
      ? /http.*\/other-assets\/icons-[-\w]{8}\.css/
      : isBundledDev
        ? /\/assets\/icons-[-\w]{8}\.css/
        : '/css/icons.css',
  )
  isBuild &&
    expect(findAssetFile(/index.*\.js$/, 'relative-base', 'entries')).toMatch(
      /icons-.+\.css(?!\?used)/,
    )
})

test('new URL(..., import.meta.url)', async () => {
  const absoluteImgMatch = isBuild
    ? /http.*\/other-assets\/img-[-\w]{8}\.png/
    : isBundledDev
      ? /\/assets\/img-[-\w]{8}\.png/
      : '/import-meta-url/img.png'
  expect(await page.textContent('.import-meta-url')).toMatch(absoluteImgMatch)
})

test('new URL(`${dynamic}`, import.meta.url)', async () => {
  const dynamic1 = await page.textContent('.dynamic-import-meta-url-1')
  expect(dynamic1).toMatch(absoluteIconMatch)
  const dynamic2 = await page.textContent('.dynamic-import-meta-url-2')
  expect(dynamic2).toMatch(absoluteAssetMatch)
})

test('new URL(`non-existent`, import.meta.url)', async () => {
  expect(await page.textContent('.non-existent-import-meta-url')).toMatch(
    '/non-existent',
  )
})

test('inline style test', async () => {
  expect(await getBg('.inline-style')).toMatch(cssBgAssetMatch)
  expect(await getBg('.style-url-assets')).toMatch(cssBgAssetMatch)
})

test('html import word boundary', async () => {
  expect(await page.textContent('.obj-import-express')).toMatch(
    'ignore object import prop',
  )
  expect(await page.textContent('.string-import-express')).toMatch('no load')
})

test('relative path in html asset', async () => {
  expect(await page.textContent('.relative-js')).toMatch('hello')
  expect(await getColor('.relative-css')).toMatch('red')
})


#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main()
{
    // create a JSON value
    json value = { {"translation", {{"one", "eins"}, {"two", "zwei"}}} };

    // create an object_t
    json::object_t object = {{"cow", "Kuh"}, {"dog", "Hund"}};

    // swap the object stored in the JSON value
    value["translation"].swap(object);

    // output the values
    std::cout << "value = " << value << '\n';
    std::cout << "object = " << object << '\n';
}


// this is written in ESM but the file extension implies this is evaluated as CJS.
// BUT this doesn't matter in practice as the `module` condition is not used in node.
// hence SSR should not load this file.
export default '[fail] should not load me'


import { execFile } from 'node:child_process'
import { promisify } from 'node:util'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { setTimeout } from 'node:timers/promises'
import { describe, expect, test } from 'vitest'
import { port, serverLogs } from './serve'
import { editFile, isServe, page } from '~utils'

const url = `http://localhost:${port}`

describe.runIf(isServe)('injected inline scripts', () => {
  test('no injected inline scripts are present', async () => {
    await page.goto(url)
    const inlineScripts = await page.$$eval('script', (nodes) =>
      nodes.filter((n) => !n.getAttribute('src') && n.innerHTML),
    )
    expect(inlineScripts).toHaveLength(0)
  })

  test('injected script proxied correctly', async () => {
    await page.goto(url)
    const proxiedScripts = await page.$$eval('script', (nodes) =>
      nodes
        .filter((n) => {
          const src = n.getAttribute('src')
          if (!src) return false
          return src.includes('?html-proxy&index')
        })
        .map((n) => n.getAttribute('src')),
    )

    // assert at least 1 proxied script exists
    expect(proxiedScripts).not.toHaveLength(0)

    const scriptContents = await Promise.all(
      proxiedScripts.map((src) => fetch(url + src).then((res) => res.text())),
    )

    // all proxied scripts return code
    for (const code of scriptContents) {
      expect(code).toBeTruthy()
    }
  })
})

describe.runIf(isServe)('trailing slash html paths', () => {
  test('pre-transforms relative module scripts from the trailing slash directory', async () => {
    serverLogs.length = 0

    const response = await fetch(`${url}/trailing-slash/dir/`)
    expect(response.status).toBe(200)
    await response.text()

    await setTimeout(100) // wait for pre-transform to happen
    expect(serverLogs).not.toEqual(
      expect.arrayContaining([expect.stringContaining('Pre-transform error')]),
    )
  })

  test('loads relative module scripts from the trailing slash directory', async () => {
    await page.goto(`${url}/trailing-slash/dir/`)

    await expect
      .poll(() => page.textContent('.relative-script'))
      .toBe('relative module loaded')
    await expect
      .poll(() => page.textContent('.relative-parent-script'))
      .toBe('relative parent module loaded')
  })
})

describe.runIf(isServe)('hmr', () => {
  test('handle virtual module updates', async () => {
    await page.goto(url)
    const el = await page.$('.virtual')
    expect(await el.textContent()).toBe('[success]')

    const loadPromise = page.waitForEvent('load')
    editFile('src/importedVirtual.js', (code) =>
      code.replace('[success]', '[wow]'),
    )
    await loadPromise

    await expect
      .poll(async () => {
        const el = await page.$('.virtual')
        return await el.textContent()
      })
      .toMatch('[wow]')
  })
})

const execFileAsync = promisify(execFile)

describe.runIf(isServe)('stacktrace', () => {
  for (const ext of ['js', 'ts']) {
    for (const sourcemapsEnabled of [false, true]) {
      test(`stacktrace of ${ext} is correct when sourcemaps is${
        sourcemapsEnabled ? '' : ' not'
      } enabled in Node.js`, async () => {
        const testStacktraceFile = path.resolve(
          import.meta.dirname,
          '../test-stacktrace.js',
        )

        const p = await execFileAsync('node', [
          testStacktraceFile,
          '' + sourcemapsEnabled,
          ext,
        ])
        const lines = p.stdout
          .split('\n')
          .filter((line) => line.includes('Module.error'))

        const reg = new RegExp(
          path
            .resolve(import.meta.dirname, '../src', `error-${ext}.${ext}`)
            .replace(/\\/g, '\\\\') + ':2:9',
          'i',
        )

        lines.forEach((line) => {
          expect(line.trim()).toMatch(reg)
        })
      })
    }
  }

  test('with Vite runtime', async () => {
    await execFileAsync('node', ['test-stacktrace-runtime.js'], {
      cwd: fileURLToPath(new URL('..', import.meta.url)),
    })
  })
})

// --experimental-network-imports is going to be dropped
// https://github.com/nodejs/node/pull/53822
const noNetworkImports = Number(process.version.match(/^v(\d+)\./)[1]) >= 22

describe.runIf(isServe && !noNetworkImports)('network-imports', () => {
  test('with Vite SSR', async () => {
    await execFileAsync(
      'node',
      ['--experimental-network-imports', 'test-network-imports.js'],
      {
        cwd: fileURLToPath(new URL('..', import.meta.url)),
      },
    )
  })

  test('with Vite runtime', async () => {
    await execFileAsync(
      'node',
      [
        '--experimental-network-imports',
        'test-network-imports.js',
        '--module-runner',
      ],
      {
        cwd: fileURLToPath(new URL('..', import.meta.url)),
      },
    )
  })
})


// @ts-nocheck
import '../nested/main'
import '../nested-with-extends/main'
import './decorator'

// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import { MainTypeOnlyClass } from './not-used-type'

class MainBase {
  set data(value: string) {
    console.log('data setter in MainBase')
  }
}
class MainDerived extends MainBase {
  // No longer triggers a 'console.log'
  // when using 'useDefineForClassFields'.
  data = 10

  foo?: MainTypeOnlyClass
}

const d = new MainDerived()


# <small>nlohmann::json_sax::</small>number_integer

```cpp
virtual bool number_integer(number_integer_t val) = 0;
```

An integer number was read.

## Parameters

`val` (in)
:   integer value

## Return value

Whether parsing should proceed.

## Examples

??? example

    The example below shows how the SAX interface is used.

    ```cpp
    --8<-- "examples/sax_parse.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/sax_parse.output"
    ```

## Version history

- Added in version 3.2.0.


import flask
from flask.globals import app_ctx
from flask.sessions import SessionInterface

def test_open_session_with_endpoint():
    """If request.endpoint (or other URL matching behavior) is needed
    while loading the session, RequestContext.match_request() can be
    called manually.
    """

    class MySessionInterface(SessionInterface):
        def save_session(self, app, session, response):
            pass

        def open_session(self, app, request):
            app_ctx.match_request()
            assert request.endpoint is not None

    app = flask.Flask(__name__)
    app.session_interface = MySessionInterface()

    @app.get("/")
    def index():
        return "Hello, World!"

    response = app.test_client().get("/")
    assert response.status_code == 200


//===- FuzzerUtilDarwin.cpp - Misc utils ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Misc utils for Darwin.
//===----------------------------------------------------------------------===//
#include "FuzzerDefs.h"
#if LIBFUZZER_APPLE

#include "FuzzerIO.h"
#include <mutex>
#include <signal.h>
#include <spawn.h>
#include <sys/wait.h>

// There is no header for this on macOS so declare here
extern "C" char **environ;

namespace fuzzer {

static std::mutex SignalMutex;
// Global variables used to keep track of how signal handling should be
// restored. They should **not** be accessed without holding `SignalMutex`.
static int ActiveThreadCount = 0;
static struct sigaction OldSigIntAction;
static struct sigaction OldSigQuitAction;
static sigset_t OldBlockedSignalsSet;

// This is a reimplementation of Libc's `system()`. On Darwin the Libc
// implementation contains a mutex which prevents it from being used
// concurrently. This implementation **can** be used concurrently. It sets the
// signal handlers when the first thread enters and restores them when the last
// thread finishes execution of the function and ensures this is not racey by
// using a mutex.
int ExecuteCommand(const std::string &Command) {
  posix_spawnattr_t SpawnAttributes;
  if (posix_spawnattr_init(&SpawnAttributes))
    return -1;
  // Block and ignore signals of the current process when the first thread
  // enters.
  {
    std::lock_guard<std::mutex> Lock(SignalMutex);
    if (ActiveThreadCount == 0) {
      static struct sigaction IgnoreSignalAction;
      sigset_t BlockedSignalsSet;
      memset(&IgnoreSignalAction, 0, sizeof(IgnoreSignalAction));
      IgnoreSignalAction.sa_handler = SIG_IGN;

      if (sigaction(SIGINT, &IgnoreSignalAction, &OldSigIntAction) == -1) {
        Printf("Failed to ignore SIGINT\n");
        (void)posix_spawnattr_destroy(&SpawnAttributes);
        return -1;
      }
      if (sigaction(SIGQUIT, &IgnoreSignalAction, &OldSigQuitAction) == -1) {
        Printf("Failed to ignore SIGQUIT\n");
        // Try our best to restore the signal handlers.
        (void)sigaction(SIGINT, &OldSigIntAction, NULL);
        (void)posix_spawnattr_destroy(&SpawnAttributes);
        return -1;
      }

      (void)sigemptyset(&BlockedSignalsSet);
      (void)sigaddset(&BlockedSignalsSet, SIGCHLD);
      if (sigprocmask(SIG_BLOCK, &BlockedSignalsSet, &OldBlockedSignalsSet) ==
          -1) {
        Printf("Failed to block SIGCHLD\n");
        // Try our best to restore the signal handlers.
        (void)sigaction(SIGQUIT, &OldSigQuitAction, NULL);
        (void)sigaction(SIGINT, &OldSigIntAction, NULL);
        (void)posix_spawnattr_destroy(&SpawnAttributes);
        return -1;
      }
    }
    ++ActiveThreadCount;
  }

  // NOTE: Do not introduce any new `return` statements past this
  // point. It is important that `ActiveThreadCount` always be decremented
  // when leaving this function.

  // Make sure the child process uses the default handlers for the
  // following signals rather than inheriting what the parent has.
  sigset_t DefaultSigSet;
  (void)sigemptyset(&DefaultSigSet);
  (void)sigaddset(&DefaultSigSet, SIGQUIT);
  (void)sigaddset(&DefaultSigSet, SIGINT);
  (void)posix_spawnattr_setsigdefault(&SpawnAttributes, &DefaultSigSet);
  // Make sure the child process doesn't block SIGCHLD
  (void)posix_spawnattr_setsigmask(&SpawnAttributes, &OldBlockedSignalsSet);
  short SpawnFlags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
  (void)posix_spawnattr_setflags(&SpawnAttributes, SpawnFlags);

  pid_t Pid;
  char **Environ = environ; // Read from global
  const char *CommandCStr = Command.c_str();
  const char *Argv[] = {"sh", "-c", CommandCStr, NULL};
  int ErrorCode = 0, ProcessStatus = 0;
  // FIXME: We probably shouldn't hardcode the shell path.
  ErrorCode = posix_spawn(&Pid, "/bin/sh", NULL, &SpawnAttributes,
                          (char *const *)Argv, Environ);
  (void)posix_spawnattr_destroy(&SpawnAttributes);
  if (!ErrorCode) {
    pid_t SavedPid = Pid;
    do {
      // Repeat until call completes uninterrupted.
      Pid = waitpid(SavedPid, &ProcessStatus, /*options=*/0);
    } while (Pid == -1 && errno == EINTR);
    if (Pid == -1) {
      // Fail for some other reason.
      ProcessStatus = -1;
    }
  } else if (ErrorCode == ENOMEM || ErrorCode == EAGAIN) {
    // Fork failure.
    ProcessStatus = -1;
  } else {
    // Shell execution failure.
    ProcessStatus = W_EXITCODE(127, 0);
  }

  // Restore the signal handlers of the current process when the last thread
  // using this function finishes.
  {
    std::lock_guard<std::mutex> Lock(SignalMutex);
    --ActiveThreadCount;
    if (ActiveThreadCount == 0) {
      bool FailedRestore = false;
      if (sigaction(SIGINT, &OldSigIntAction, NULL) == -1) {
        Printf("Failed to restore SIGINT handling\n");
        FailedRestore = true;
      }
      if (sigaction(SIGQUIT, &OldSigQuitAction, NULL) == -1) {
        Printf("Failed to restore SIGQUIT handling\n");
        FailedRestore = true;
      }
      if (sigprocmask(SIG_BLOCK, &OldBlockedSignalsSet, NULL) == -1) {
        Printf("Failed to unblock SIGCHLD\n");
        FailedRestore = true;
      }
      if (FailedRestore)
        ProcessStatus = -1;
    }
  }
  return ProcessStatus;
}

} // namespace fuzzer

#endif // LIBFUZZER_APPLE