ecma-re-validator-0.4.0/0000755000004100000410000000000014173312143015036 5ustar www-datawww-dataecma-re-validator-0.4.0/ecma-re-validator.gemspec0000644000004100000410000000232314173312143021677 0ustar www-datawww-data# frozen_string_literal: true $LOAD_PATH.push File.expand_path('lib', __dir__) require 'ecma-re-validator/version' Gem::Specification.new do |gem| gem.name = 'ecma-re-validator' gem.version = EcmaReValidator::VERSION gem.authors = ['Garen Torikian'] gem.email = ['gjtorikian@gmail.com'] gem.description = %(Validate a regular expression string against what ECMA-262 can actually do.) gem.summary = %(Validate a regular expression string against what ECMA-262 can actually do.) gem.homepage = 'https://github.com/gjtorikian/ecma-re-validator' gem.license = 'MIT' gem.files = `git ls-files -z`.split("\x0").grep_v(%r{^vendor/.*}) gem.test_files = gem.files.grep(%r{^(spec)/}) gem.require_paths = ['lib'] gem.required_ruby_version = ['>= 2.6.0', '< 4.0'] gem.add_dependency 'regexp_parser', '~> 2.2' gem.add_development_dependency 'awesome_print' gem.add_development_dependency 'rake', '~> 13.0' gem.add_development_dependency 'rspec', '~> 3.1' gem.add_development_dependency 'rubocop' gem.add_development_dependency 'rubocop-rspec' gem.add_development_dependency 'rubocop-standard' gem.metadata['rubygems_mfa_required'] = 'true' end ecma-re-validator-0.4.0/README.md0000644000004100000410000000067214173312143016322 0ustar www-datawww-data# ecma-re-validator Pass in a string to validate if it would work in ECMA-262, aka JavaScript. The information for what is valid and what isn't comes from . ## Usage Pass in either a string or a Regexp: ``` ruby require 'ecma-re-validator' re = "[Ss]mith\\\\b" EcmaReValidator.valid?(re) # true re = /(?<=a)b/ EcmaReValidator.valid?(re) # false--lookbehinds don't exist in JS ``` ecma-re-validator-0.4.0/spec/0000755000004100000410000000000014173312143015770 5ustar www-datawww-dataecma-re-validator-0.4.0/spec/conditionals_spec.rb0000644000004100000410000000107114173312143022014 0ustar www-datawww-data# frozen_string_literal: true require 'spec_helper' describe 'EcmaReValidator::Conditionals' do it 'should pass if regexp is using just (?...)' do re = '(?:Aa)' expect(EcmaReValidator.valid?(re)).to eql(true) end it 'should fail if regexp is using complicated if-then-else' do re = '(?(?=condition)(then1|then2|then3)|(else1|else2|else3))' expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp is using basic if-then-else' do re = 'b(?(1)c|d)' expect(EcmaReValidator.valid?(re)).to eql(false) end end ecma-re-validator-0.4.0/spec/mode_modifiers_spec.rb0000644000004100000410000000117114173312143022314 0ustar www-datawww-data# frozen_string_literal: true require 'spec_helper' describe 'EcmaReValidator::ModeModifiers' do it 'should fail if regexp has simple option' do re = '(?i)test' expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp has multiple options' do re = '(?ism)test' expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp has colon option' do re = '(?mix:abc)' expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp has hyphen option' do re = 'te(?-i)st' expect(EcmaReValidator.valid?(re)).to eql(false) end end ecma-re-validator-0.4.0/spec/comments_spec.rb0000644000004100000410000000106014173312143021151 0ustar www-datawww-data# frozen_string_literal: true require 'spec_helper' describe 'EcmaReValidator::Comments' do it 'should fail if regexp has inline comments' do re = /(?#comment)hello/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp has inline comments across lines' do re = / start # some text \s # white space char (group) # first group (?:alt1|alt2) # some alternation end /x expect(EcmaReValidator.valid?(re)).to eql(false) end end ecma-re-validator-0.4.0/spec/unicode_spec.rb0000644000004100000410000000465714173312143020771 0ustar www-datawww-data# frozen_string_literal: true require 'spec_helper' describe 'EcmaReValidator::Unicode' do it 'should fail if regexp uses \p{L} or \p{Letter}' do re = /\p{L}/ expect(EcmaReValidator.valid?(re)).to eql(false) re = /\p{Letter}/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp uses \p{M} or \p{Mark}' do re = /\p{M}/ expect(EcmaReValidator.valid?(re)).to eql(false) re = /\p{Mark}/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp uses \p{Z} or \p{Separator}' do re = /\p{Z}/ expect(EcmaReValidator.valid?(re)).to eql(false) re = /\p{Separator}/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp uses \p{S} or \p{Symbol}' do re = /\p{S}/ expect(EcmaReValidator.valid?(re)).to eql(false) re = /\p{Symbol}/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp uses \p{N} or \p{Number}' do re = /\p{N}/ expect(EcmaReValidator.valid?(re)).to eql(false) re = /\p{Number}/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp uses \p{P} or \p{Punctuation}' do re = /\p{P}/ expect(EcmaReValidator.valid?(re)).to eql(false) re = /\p{Punctuation}/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp uses \p{C} or \p{Other}' do re = /\p{C}/ expect(EcmaReValidator.valid?(re)).to eql(false) re = /\p{Other}/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp uses a script' do re = /\p{Armenian}/ expect(EcmaReValidator.valid?(re)).to eql(false) end # not yet supported # it 'should fail if regexp uses a block' do # re = /\p{InArmenian}/ # # expect(EcmaReValidator.valid?(re)).to eql(false) # end it 'should pass if regexp uses a \u' do re = /\uf8f8/ expect(EcmaReValidator.valid?(re)).to eql(true) end it 'should pass if regexp uses a \x' do re = /\x22/ expect(EcmaReValidator.valid?(re)).to eql(true) end it 'should pass if regexp uses a \w' do re = /^\w+/ expect(EcmaReValidator.valid?(re)).to eql(true) end it 'should pass if regexp uses a \s' do re = /\s*wow/ expect(EcmaReValidator.valid?(re)).to eql(true) end it 'should pass if regexp uses a \d' do re = /\d$/ expect(EcmaReValidator.valid?(re)).to eql(true) end end ecma-re-validator-0.4.0/spec/lookbehind_spec.rb0000644000004100000410000000124314173312143021445 0ustar www-datawww-data# frozen_string_literal: true require 'spec_helper' describe 'EcmaReValidator::Lookbehind' do it 'should fail if regexp has a positive lookbehind' do re = '(?<=a)b' expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should pass if regexp has an escaped positive lookbehind' do re = '\\(?<=a\\)b' expect(EcmaReValidator.valid?(re)).to eql(true) end it 'should fail if regexp has a negative lookbehind' do re = '(?integer|insert|in)\b./ expect(EcmaReValidator.valid?(re)).to eql(false) end end ecma-re-validator-0.4.0/spec/validator_spec.rb0000644000004100000410000000110714173312143021313 0ustar www-datawww-data# frozen_string_literal: true require 'spec_helper' describe 'EcmaRe' do it 'should fail if input is not a string or regexp' do re = 92 expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if string is not resolvable' do re = '(\w' expect(EcmaReValidator.valid?(re)).to eql(false) end it 'passes for a valid regexp string' do re = '[Ss]mith\\\\b' expect(EcmaReValidator.valid?(re)).to eql(true) end it 'passes for a valid regexp' do re = /[Ss]mith\\\\b/ expect(EcmaReValidator.valid?(re)).to eql(true) end end ecma-re-validator-0.4.0/spec/named_capture_groups_spec.rb0000644000004100000410000000063714173312143023543 0ustar www-datawww-data# frozen_string_literal: true require 'spec_helper' describe 'EcmaReValidator::NamedCaptureGroups' do it 'should fail if regexp has named capture group using ?<>' do re = /(?group)/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp has named capture group using ?\'\'' do re = /(?'name'group)/ expect(EcmaReValidator.valid?(re)).to eql(false) end end ecma-re-validator-0.4.0/spec/possesive_quantifiers_spec.rb0000644000004100000410000000102414173312143023756 0ustar www-datawww-data# frozen_string_literal: true require 'spec_helper' describe 'EcmaReValidator::PossesiveQuantifiers' do it 'should fail if regexp has *+ possesive quantifier' do re = /"[^"]*+"/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp has ++ possesive quantifier' do re = /"[^"]++"/ expect(EcmaReValidator.valid?(re)).to eql(false) end it 'should fail if regexp has ?+ possesive quantifier' do re = /"[^"]?+"/ expect(EcmaReValidator.valid?(re)).to eql(false) end end ecma-re-validator-0.4.0/.rubocop.yml0000644000004100000410000000013514173312143017307 0ustar www-datawww-datainherit_gem: rubocop-standard: - config/default.yml Naming/FileName: Enabled: false ecma-re-validator-0.4.0/.gitignore0000644000004100000410000000040614173312143017026 0ustar www-datawww-data*.gem *.rbc .bundle .config coverage InstalledFiles lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp vendor/cache Gemfile.lock out/ sample.rb run_sample.rb src/ docs/ # YARD artifacts .yardoc _yardoc .DS_Store .idea .byebug_history .vscode ecma-re-validator-0.4.0/script/0000755000004100000410000000000014173312143016342 5ustar www-datawww-dataecma-re-validator-0.4.0/script/cibuild0000755000004100000410000000005114173312143017677 0ustar www-datawww-data#!/bin/sh set -e bundle exec rake spec ecma-re-validator-0.4.0/script/bootstrap0000755000004100000410000000011014173312143020275 0ustar www-datawww-data#!/bin/bash bundle install --local --binstubs --path vendor/cache "$@" ecma-re-validator-0.4.0/Rakefile0000644000004100000410000000035114173312143016502 0ustar www-datawww-data# frozen_string_literal: true require 'bundler' Bundler::GemHelper.install_tasks require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) task default: [:spec] require 'rubocop/rake_task' RuboCop::RakeTask.new(:rubocop) ecma-re-validator-0.4.0/lib/0000755000004100000410000000000014173312143015604 5ustar www-datawww-dataecma-re-validator-0.4.0/lib/ecma-re-validator.rb0000644000004100000410000000232614173312143021430 0ustar www-datawww-data# frozen_string_literal: true require 'regexp_parser' module EcmaReValidator # JS doesn't have Unicode matching UNICODE_CHARACTERS = Regexp::Syntax::Token::UnicodeProperty::All INVALID_REGEXP = [ # JS doesn't have \A, \Z, \z :bos, :eos_ob_eol, :eos, # JS doesn't have lookbehinds :lookbehind, :nlookbehind, # JS doesn't have atomic grouping :atomic, # JS doesn't have possesive quantifiers :zero_or_one_possessive, :zero_or_more_possessive, :one_or_more_possessive, # JS doesn't have named capture groups :named_ab, :named_sq, # JS doesn't support modifying options :options, :options_switch, # JS doesn't support conditionals :condition_open, # JS doesn't support comments :comment ].freeze INVALID_TOKENS = INVALID_REGEXP + UNICODE_CHARACTERS def self.valid?(input) if input.is_a? String begin input = Regexp.new(input) rescue RegexpError return false end elsif !input.is_a? Regexp return false end Regexp::Scanner.scan(input).none? do |t| if t[1] == :word || t[1] == :space || t[1] == :digit t[0] != :type else INVALID_TOKENS.include?(t[1]) end end end end ecma-re-validator-0.4.0/lib/ecma-re-validator/0000755000004100000410000000000014173312143021100 5ustar www-datawww-dataecma-re-validator-0.4.0/lib/ecma-re-validator/version.rb0000644000004100000410000000011614173312143023110 0ustar www-datawww-data# frozen_string_literal: true module EcmaReValidator VERSION = '0.4.0' end ecma-re-validator-0.4.0/Gemfile0000644000004100000410000000010514173312143016325 0ustar www-datawww-data# frozen_string_literal: true source 'http://rubygems.org' gemspec ecma-re-validator-0.4.0/.github/0000755000004100000410000000000014173312143016376 5ustar www-datawww-dataecma-re-validator-0.4.0/.github/workflows/0000755000004100000410000000000014173312143020433 5ustar www-datawww-dataecma-re-validator-0.4.0/.github/workflows/ci.yml0000644000004100000410000000100514173312143021545 0ustar www-datawww-dataname: Ruby CI on: push: jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: ruby-version: [3.1.0, 3.0.0, 2.7.5] steps: - uses: actions/checkout@v2 - name: Set up Ruby ${{ matrix.ruby-version }} uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true - name: Install dependencies run: bundle install - name: Run tests run: bundle exec rake spec ecma-re-validator-0.4.0/.github/workflows/lint.yml0000644000004100000410000000046314173312143022127 0ustar www-datawww-dataname: Linting on: push: jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 with: ruby-version: 3.0 bundler-cache: true - run: bundle install - name: Rubocop run: bundle exec rake rubocop ecma-re-validator-0.4.0/LICENSE.txt0000644000004100000410000000207214173312143016662 0ustar www-datawww-dataThe MIT License (MIT) Copyright (c) 2015 Garen Torikian Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.