Skip to content

Readline 'cursorTo' function incorrectly treats 'NaN' as a number #36301

Closed
@unitario

Description

@unitario
  • Version: v14.9.0
  • Platform: Darwin computer 19.6.0 Darwin Kernel Version 19.6.0: Mon Aug 31 22:12:52 PDT 2020; root:xnu-6153.141.2~1/RELEASE_X86_64 x86_64
  • Subsystem: x86_64

What steps will reproduce the bug?

> node --print 'process.stdout.cursorTo(2, NaN)'

or

> node --print 'process.stdout.cursorTo(NaN, 2)'

How often does it reproduce? Is there a required condition?

Anytime NaN is passed as either x or y coordinates to the cursorTo function.

What is the expected behavior?

When y parameter is NaN, it should throw ERR_INVALID_CURSOR_POS, and log true in the terminal.

> node --print 'process.stdout.cursorTo(2, NaN)'
> true

When x parameter is NaN, the if statement for the data variable should evaluate to CSI${x + 1}G, and log true in the terminal.

> node --print 'process.stdout.cursorTo(NaN, 2)'
> true

What do you see instead?

> node --print 'process.stdout.cursorTo(2, NaN)'
> aN;1Htrue

or

> node --print 'process.stdout.cursorTo(NaN, 2)'
> aNHtrue

Additional information

Change:

/**
 * moves the cursor to the x and y coordinate on the given stream
 */

function cursorTo(stream, x, y, callback) {
  if (callback !== undefined && typeof callback !== 'function')
    throw new ERR_INVALID_CALLBACK(callback);

  if (typeof y === 'function') {
    callback = y;
    y = undefined;
  }

  if (stream == null || (typeof x !== 'number' && typeof y !== 'number')) {
    if (typeof callback === 'function')
      process.nextTick(callback, null);
    return true;
  }

  if (typeof x !== 'number')
    throw new ERR_INVALID_CURSOR_POS();

  const data = typeof y !== 'number' ? CSI`${x + 1}G` : CSI`${y + 1};${x + 1}H`;
  return stream.write(data, callback);
}

Into:

/**
 * moves the cursor to the x and y coordinate on the given stream
 */

function cursorTo(stream, x, y, callback) {
  if (callback !== undefined && typeof callback !== 'function')
    throw new ERR_INVALID_CALLBACK(callback);

  if (typeof y === 'function') {
    callback = y;
    y = undefined;
  }

  if (stream == null || (isNaN(x) && isNaN(y))) {
    if (typeof callback === 'function')
      process.nextTick(callback, null);
    return true;
  }

  if (isNaN(x))
    throw new ERR_INVALID_CURSOR_POS();

  const data = isNaN(y) ? CSI`${x + 1}G` : CSI`${y + 1};${x + 1}H`;
  return stream.write(data, callback);
}

Source: https://github.com/nodejs/node/blob/master/lib/readline.js

Metadata

Metadata

Assignees

No one assigned

    Labels

    readlineIssues and PRs related to the built-in readline module.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions