ruby-jing 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jing.rb +19 -8
  3. data/test/test_jing.rb +41 -18
  4. metadata +8 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b1085cc25a09ba6773d7b0dfb4e6f8049054aaadccff23342b7a69861a64584
4
- data.tar.gz: a033dc727afee925c526ec476f68a25b7e491efb6f5e799a755484e6c2d996d4
3
+ metadata.gz: 41284b05a5ee61d28bbf52115ad2c910ee85791edf63880786ac413f9d190b71
4
+ data.tar.gz: e373a5ca42a69b3f6bd7a663155239904cc0f2fd8fd2033ebd19f8586ac2490a
5
5
  SHA512:
6
- metadata.gz: 1186148de2672e4ea4924cc7065878d3ce7a1d94732517bfb7159a613ffeb12bbec509b7bddf50c84ad2121ecf885e5a365edd09d2222562e89bcc8d0c872bbe
7
- data.tar.gz: 9211e3e156bf374b48f32814c058a80d63df45ab6261e1726296b2ef319b037d4f045c199596e2b1efd95298a7c84da03c693a8138335b68fa417dee548025f6
6
+ metadata.gz: 858919ea520690526014c81aeba7f77308933dbd4afcc52fe2a1e40d8a5f1d8f1267b2dd133c5617cdd60cec8f7934595d03fab0ac087c6fdadbb9203a91cddb
7
+ data.tar.gz: 94c9479f1a222b58b81d150806c3d937913436cdb4c2c35d29892ce06be0d7f405400ff8284cbddc9c1caa443ac38e76ab3f0706a65e435863b3b8d98efa57d7
data/lib/jing.rb CHANGED
@@ -1,7 +1,8 @@
1
+ require "open3"
1
2
  require "optout"
2
3
 
3
4
  class Jing
4
- VERSION = "0.0.3"
5
+ VERSION = "0.1.0"
5
6
  DEFAULT_JAR = File.join(File.dirname(__FILE__), "jing-20091111.jar")
6
7
 
7
8
  Error = Class.new(StandardError)
@@ -32,6 +33,7 @@ class Jing
32
33
  # === Options
33
34
  #
34
35
  # [:java (String)] Name and/or location of the java executable. Defaults to <code>"java"</code>.
36
+ # [:java_opts (String)] JVM options passed to +java+, e.g. +"-Dfile.encoding=UTF-8"+. Use this to set +"-D"+ system properties (e.g. +jdk.xml.maxGeneralEntitySizeLimit+) instead of the +JAVA_TOOL_OPTIONS+/_JAVA_OPTIONS+ environment variables, which make the JVM print a +Picked up ...+ banner to stderr on every launch.
35
37
  # [:jar (String)] Path to the Jing JAR file. Defaults to the bundled JAR.
36
38
  # [:compact (Boolean)] Set to +true+ if the schema uses the RELAX NG compact syntax. Defaults to false, will be set to +true+ is the schema has a +.rnc+ extension.
37
39
  # [:encoding (String)] Encoding of the XML document.
@@ -53,7 +55,8 @@ class Jing
53
55
  # Optout quirk: true will *include* the switch, which means we *don't* want to check
54
56
  @options[:id_check] = !@options[:id_check] if @options.include?(:id_check)
55
57
  if @options[:encoding]
56
- @options[:java_opts] = "-Dfile.encoding=#{@options[:encoding]}"
58
+ file_encoding = "-Dfile.encoding=#{@options[:encoding]}"
59
+ @options[:java_opts] = [@options[:java_opts], file_encoding].compact.join(" ")
57
60
  end
58
61
  end
59
62
 
@@ -87,8 +90,8 @@ class Jing
87
90
  def validate(xml)
88
91
  @options[:xmlfile] = xml
89
92
 
90
- out = execute(@options)
91
- return [] if $?.success? and out.empty?
93
+ out, status = execute(@options)
94
+ return [] if status.success? and out.empty?
92
95
 
93
96
  parse_output(out)
94
97
  end
@@ -116,9 +119,16 @@ class Jing
116
119
  end
117
120
 
118
121
  private
122
+ # Spawn java directly in argv form instead of shelling out via backticks.
123
+ # A shell-form spawn needs /bin/sh, which is not always reachable from the
124
+ # calling process (restricted containers, TruffleRuby processes with a
125
+ # virtual filesystem mounted at /, ...); direct exec needs no shell. It
126
+ # also removes the shell-injection surface of interpolating paths into a
127
+ # command string. Behavior is unchanged: stderr is merged into the
128
+ # captured output and the exit status is returned alongside it.
119
129
  def execute(options)
120
- cmd = @@option_builder.shell(options)
121
- `#{cmd} 2>&1`
130
+ argv = @@option_builder.argv(options)
131
+ Open3.capture2e(*argv)
122
132
  rescue SystemCallError => e
123
133
  raise ExecutionError, "jing execution failed: #{e}"
124
134
  rescue Optout::OptionError => e
@@ -136,8 +146,9 @@ class Jing
136
146
  :column => $3.to_i,
137
147
  :message => $4
138
148
  }
139
- when /Picked up _JAVA_OPTIONS: /
140
- # ignore diagnostic message
149
+ when /Picked up [A-Z_][A-Z0-9_]*: /
150
+ # ignore JVM diagnostic banner printed for env vars like
151
+ # _JAVA_OPTIONS, JAVA_TOOL_OPTIONS and JDK_JAVA_OPTIONS
141
152
  else # There must have been a problem that was not schema related
142
153
  raise ExecutionError, output
143
154
  end
data/test/test_jing.rb CHANGED
@@ -12,7 +12,7 @@ class TestJing < MiniTest::Unit::TestCase
12
12
 
13
13
  def test_default_jar_file_used
14
14
  cmd = fakeshell { Jing.new(RNG_SCHEMA).validate(VALID_XML) }
15
- assert_match /\A'java'\s+ -jar\s+ '#{Jing::DEFAULT_JAR}' \s+/x, cmd
15
+ assert_match /\Ajava\s+ -jar\s+ #{Regexp.escape(Jing::DEFAULT_JAR)} \s+/x, cmd
16
16
  end
17
17
 
18
18
  def test_jar_file_must_exist
@@ -24,13 +24,13 @@ class TestJing < MiniTest::Unit::TestCase
24
24
  def test_jar_option
25
25
  jar = Tempfile.new "jar"
26
26
  cmd = fakeshell { Jing.new(RNG_SCHEMA, :jar => jar.path).validate(VALID_XML) }
27
- assert_match /\A'java'\s+ -jar\s+ '#{jar.path}' \s+/x, cmd
27
+ assert_match /\Ajava\s+ -jar\s+ #{Regexp.escape(jar.path)} \s+/x, cmd
28
28
  end
29
29
 
30
30
  def test_java_option
31
31
  java = "/usr/alt/java"
32
32
  cmd = fakeshell { Jing.new(RNG_SCHEMA, :java => java).validate(VALID_XML) }
33
- assert_match /\A'#{java}'\s+/, cmd
33
+ assert_match /\A#{Regexp.escape(java)}\s+/, cmd
34
34
  end
35
35
 
36
36
  def test_java_must_exist
@@ -43,12 +43,12 @@ class TestJing < MiniTest::Unit::TestCase
43
43
  def test_encoding_option
44
44
  enc = "iso-8859-1"
45
45
  cmd = fakeshell { Jing.new(RNG_SCHEMA, :encoding => enc).validate(VALID_XML) }
46
- assert_match /\A'java'\s+ '-Dfile.encoding=#{enc}'\s+ -jar\s+ '#{Jing::DEFAULT_JAR}'\s+ -e\s+ '#{enc}'/x, cmd
46
+ assert_match /\Ajava\s+ -Dfile\.encoding=#{enc}\s+ -jar\s+ #{Regexp.escape(Jing::DEFAULT_JAR)}\s+ -e\s+ #{enc}/x, cmd
47
47
  end
48
48
 
49
49
  def test_id_check_option
50
50
  cmd = fakeshell { Jing.new(RNG_SCHEMA, :id_check => false).validate(VALID_XML) }
51
- assert_match /\A'java'\s -jar\s+ '#{Jing::DEFAULT_JAR}'\s+ -i/x, cmd
51
+ assert_match /\Ajava\s -jar\s+ #{Regexp.escape(Jing::DEFAULT_JAR)}\s+ -i/x, cmd
52
52
 
53
53
  cmd = fakeshell { Jing.new(RNG_SCHEMA, :id_check => true).validate(VALID_XML) }
54
54
  refute_match /\b-i\b/x, cmd
@@ -59,7 +59,7 @@ class TestJing < MiniTest::Unit::TestCase
59
59
 
60
60
  def test_compact_option
61
61
  cmd = fakeshell { Jing.new(RNC_SCHEMA, :compact => true).validate(VALID_XML) }
62
- assert_match /\A'java'\s -jar\s+ '#{Jing::DEFAULT_JAR}'\s+ -c/x, cmd
62
+ assert_match /\Ajava\s -jar\s+ #{Regexp.escape(Jing::DEFAULT_JAR)}\s+ -c/x, cmd
63
63
 
64
64
  cmd = fakeshell { Jing.new(RNC_SCHEMA, :compact => false).validate(VALID_XML) }
65
65
  refute_match /\b-c\b/, cmd
@@ -67,7 +67,7 @@ class TestJing < MiniTest::Unit::TestCase
67
67
 
68
68
  def test_compact_option_when_compact_schema_is_used
69
69
  cmd = fakeshell { Jing.new(RNC_SCHEMA).validate(VALID_XML) }
70
- assert_match /\A'java'\s+ -jar\s+ '#{Jing::DEFAULT_JAR}'\s+ -c/x, cmd
70
+ assert_match /\Ajava\s+ -jar\s+ #{Regexp.escape(Jing::DEFAULT_JAR)}\s+ -c/x, cmd
71
71
  end
72
72
 
73
73
  def test_relaxng_file_must_exist
@@ -121,28 +121,51 @@ class TestJing < MiniTest::Unit::TestCase
121
121
  }
122
122
  end
123
123
 
124
+ def test_java_tool_options_env_diagnostic_message
125
+ output = "Picked up JAVA_TOOL_OPTIONS: -Djdk.xml.maxGeneralEntitySizeLimit=200000"
126
+ fakeshell(:exit => 0, :output => output) {
127
+ errors = Jing.new(RNG_SCHEMA).validate(VALID_XML)
128
+ assert_equal 0, errors.size
129
+ }
130
+ end
131
+
132
+ def test_jdk_java_options_env_diagnostic_message
133
+ output = "Picked up JDK_JAVA_OPTIONS: -Dfile.encoding=UTF-8"
134
+ fakeshell(:exit => 0, :output => output) {
135
+ errors = Jing.new(RNG_SCHEMA).validate(VALID_XML)
136
+ assert_equal 0, errors.size
137
+ }
138
+ end
139
+
140
+ def test_java_opts_and_encoding_are_combined
141
+ opts = "-Djdk.xml.maxGeneralEntitySizeLimit=200000"
142
+ cmd = fakeshell { Jing.new(RNG_SCHEMA, :java_opts => opts, :encoding => "iso-8859-1").validate(VALID_XML) }
143
+ assert_match(/#{opts} -Dfile\.encoding=iso-8859-1\s+-jar/, cmd)
144
+ assert_match(/-e\s+ iso-8859-1/x, cmd)
145
+ end
146
+
124
147
  private
125
148
  def fakeshell(options = {})
126
149
  output = options.delete(:output) || ""
127
150
  exit_code = options.delete(:exit) || 0
128
151
 
129
152
  cmd = nil
130
- Object.class_eval do
131
- alias_method "real_tick", "`"
132
- define_method("`") do |arg|
133
- cmd = arg
134
- real_tick %{ruby -e"exit #{exit_code}"} # Just to set $?
135
- output
153
+ Open3.singleton_class.class_eval do
154
+ alias_method "real_capture2e", "capture2e"
155
+ define_method("capture2e") do |*argv|
156
+ cmd = argv.join(" ")
157
+ `ruby -e"exit #{exit_code}"` # Just to set $?
158
+ [output, $?]
136
159
  end
137
160
  end
138
161
 
139
162
  yield
140
- cmd.tr %{"}, %{'} # replace Win quotes with *nix
163
+ cmd
141
164
  ensure
142
- Object.class_eval do
143
- undef_method "`" #`
144
- alias_method "`", "real_tick"
145
- undef_method "real_tick"
165
+ Open3.singleton_class.class_eval do
166
+ undef_method "capture2e"
167
+ alias_method "capture2e", "real_capture2e"
168
+ undef_method "real_capture2e"
146
169
  end
147
170
  end
148
171
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-jing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skye Shaw
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-06-22 00:00:00.000000000 Z
10
+ date: 2026-09-17 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: optout
@@ -83,8 +82,11 @@ files:
83
82
  homepage: http://github.com/sshaw/ruby-jing
84
83
  licenses:
85
84
  - MIT
86
- metadata: {}
87
- post_install_message:
85
+ metadata:
86
+ homepage_uri: http://github.com/sshaw/ruby-jing
87
+ source_code_uri: https://github.com/sshaw/ruby-jing
88
+ bug_tracker_uri: https://github.com/sshaw/ruby-jing/issues
89
+ changelog_uri: https://github.com/sshaw/ruby-jing/blob/master/Changes
88
90
  rdoc_options: []
89
91
  require_paths:
90
92
  - lib
@@ -99,8 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
101
  - !ruby/object:Gem::Version
100
102
  version: '0'
101
103
  requirements: []
102
- rubygems_version: 3.0.3
103
- signing_key:
104
+ rubygems_version: 3.6.2
104
105
  specification_version: 4
105
106
  summary: RELAX NG schema validation using the Jing CLI
106
107
  test_files: