'use strict';

const assert = require('assert');
const { isMatch, makeRe } = require('..');
const repeat = n => '\\'.repeat(n);

/**
 * These tests are based on minimatch unit tests
 */

describe('handling of potential regex exploits', () => {
  it('should support long escape sequences', () => {
    if (process.platform !== 'win32') {
      assert(isMatch('\\A', `${repeat(65500)}A`), 'within the limits, and valid match');
    }
    assert(isMatch('A', `!${repeat(65500)}A`), 'within the limits, and valid match');
    assert(isMatch('A', `!(${repeat(65500)}A)`), 'within the limits, and valid match');
    assert(!isMatch('A', `[!(${repeat(65500)}A`), 'within the limits, but invalid regex');
  });

  it('should throw an error when the pattern is too long', () => {
    assert.throws(() => isMatch('foo', '*'.repeat(65537)), /exceeds maximum allowed/);
    assert.throws(() => {
      assert(!isMatch('A', `!(${repeat(65536)}A)`));
    }, /Input length: 65540, exceeds maximum allowed length: 65536/);
  });

  it('should allow max bytes to be customized', () => {
    assert.throws(() => {
      assert(!isMatch('A', `!(${repeat(500)}A)`, { maxLength: 499 }));
    }, /Input length: 504, exceeds maximum allowed length: 499/);
  });

  it('should be able to accept Object instance properties', () => {
    assert(isMatch('constructor', 'constructor'), 'valid match');
    assert(isMatch('__proto__', '__proto__'), 'valid match');
    assert(isMatch('toString', 'toString'), 'valid match');
  });

  it('should not expose internal prototype properties', () => {
    assert.equal(makeRe('[[:constructor:]]').toString(), '/^(?:[[:constructor:]\\])$/');
    assert(!isMatch('f }]', '[[:constructor:]]'), 'not valid match');
    assert(!isMatch('a }]', '[[:constructor:]]'),  'not valid match');
  });
});
