ppr 0.0.4 → 0.0.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3c2c8adf60e11d57a5c5bd231828482b93e9da72
4
- data.tar.gz: b2a411642ca9e8f9de4aa225779082cd5d0d1324
2
+ SHA256:
3
+ metadata.gz: 2042d52e7ba854cb3813ded3c053f15f0d62cf72e3a5c62b3b2546d9fc24e12a
4
+ data.tar.gz: c03dc06cb0f09e56efdae00063e0451389319163b4b674a3d959c22915216dfb
5
5
  SHA512:
6
- metadata.gz: 32baf77bd2913db328a208c6666bc415d752df5f498b77be528e80cb8403b84a788890f4dc1f7087362832b93a12e558b10a23c759670093152d45f6e70e8364
7
- data.tar.gz: 47bbe12fae200d8152034b76ff247aa7ccee4254f2b7a9e9ef397d29541eb4c8f3a65e36a1416e974801da4107413e7a84463da328cbf0c34cde4d0fcd4968c4
6
+ metadata.gz: 5c9c6b98dc45c18bc65a219e7c220b55bfd606d411f1bbcd28ad12bd42cd6271dc224725cb1ad8521e5211f657e3c99627883426252ad5917f9fafd07235113a
7
+ data.tar.gz: b687e440a1fd675306a070258c0b8807b2725c4a133d05602f9fb7134a1b1073c0a451d63a9f4dc2c07bba151d18ce223bd628cf543c211ccdac7f66de18e018
data/lib/ppr/ppr_core.rb CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  require "ppr/safer_generator.rb"
6
6
  require "ppr/keyword_searcher.rb"
7
+ require 'delegate'
7
8
 
8
9
  module Ppr
9
10
 
@@ -302,11 +303,26 @@ class LoadRequire < Macro
302
303
  super("",num,ppr,expand: expand)
303
304
  end
304
305
 
306
+ def set_locations(locations)
307
+ @locations = locations
308
+ end
309
+
310
+ def find_file(name)
311
+ @locations.each do |i|
312
+ filepath = i + "/" + name
313
+ if File.exist?(filepath)
314
+ return filepath
315
+ end
316
+ end
317
+
318
+ raise "File #{name} was not found in includes."
319
+ end
320
+
305
321
  # Loads and preprocess file +name+.
306
322
  def loadm(name)
307
323
  output = StringIO.new("")
308
324
  # print "name=#{name}\n"
309
- File.open(name,"r") do |input|
325
+ File.open(find_file(name),"r") do |input|
310
326
  @ppr.preprocess(input,output)
311
327
  end
312
328
  return output.string
@@ -392,7 +408,8 @@ class Preprocessor
392
408
  endm: ".end",
393
409
  expand: ":<",
394
410
  separator: /^|[^\w]|$/, glue: "##",
395
- escape: "\\")
411
+ escape: "\\",
412
+ includes: Dir.pwd)
396
413
  # Check and Initialize the keywords
397
414
  # NOTE: since there are a lot of checks, use a generic but
398
415
  # harder to read code.
@@ -453,6 +470,10 @@ class Preprocessor
453
470
  params.each do |k,v|
454
471
  parameter_set(k,v)
455
472
  end
473
+
474
+ #include folder locations to search for load and require
475
+ @includes = []
476
+ (@includes << includes).flatten!
456
477
  end
457
478
 
458
479
  # Methods for handling the execution context of the macros.
@@ -531,17 +552,17 @@ class Preprocessor
531
552
 
532
553
  # Tells if a line corresponds to an end keyword.
533
554
  def is_endm?(line)
534
- @endm.match(line)
555
+ @endm.match(line.strip)
535
556
  end
536
557
 
537
558
  # Tells if a line corresponds to an else keyword.
538
559
  def is_elsem?(line)
539
- @elsem.match(line)
560
+ @elsem.match(line.strip)
540
561
  end
541
562
 
542
563
  # Tells if a line corresponds to an endif keyword.
543
564
  def is_endifm?(line)
544
- @endifm.match(line)
565
+ @endifm.match(line.strip)
545
566
  end
546
567
 
547
568
  # Extract a macro definition from a +line+ if there is one.
@@ -606,8 +627,10 @@ class Preprocessor
606
627
  macro = Assign.new(name,@number,self,expand: @expand)
607
628
  when @loadm then
608
629
  macro = Load.new(@number,self,expand: @expand)
630
+ macro.set_locations(@includes)
609
631
  when @requirem then
610
632
  macro = Require.new(@number,self,expand: @expand)
633
+ macro.set_locations(@includes)
611
634
  when @ifm then
612
635
  macro = If.new(@number,self,expand: @expand)
613
636
  else
@@ -43,6 +43,16 @@ class SaferGenerator
43
43
  methods = DANGER_METHODS + @black_methods
44
44
  # Gather the constants to strip.
45
45
  constants = DANGER_CONSTANTS + @black_constants
46
+ # Save the dangerous methods in a private safe.
47
+ @safe_of_methods = {}
48
+ methods.each do |meth|
49
+ @safe_of_methods[meth]=method(meth)
50
+ end
51
+ # Save the dangerous constants in a private safe.
52
+ @safe_of_constants = {}
53
+ constants.each do |cst|
54
+ @safe_of_constants[cst] = Object.send(:const_get,cst)
55
+ end
46
56
  # Strip the dangerous methods.
47
57
  methods.each do |meth|
48
58
  Kernel.send(:undef_method,meth)
@@ -53,6 +63,21 @@ class SaferGenerator
53
63
  end
54
64
  end
55
65
 
66
+ # Restores all the stripped Kernel methods and constants appart from the
67
+ # elements of the white list.
68
+ # Also strip Object from dangerous methods and constants apart
69
+ # from the elements of the white list.
70
+ def unsecure
71
+ # Restores the dangerous methods in a private safe.
72
+ @safe_of_methods.each do |(name,pr)|
73
+ Kernel.send(:define_method,name,&pr)
74
+ end
75
+ # Restors the dangerous constants in a private safe.
76
+ @safe_of_constants.each do |(name,cst)|
77
+ Object.const_set(name,cst)
78
+ end
79
+ end
80
+
56
81
 
57
82
  # Executes +block+ in a safe context for generating text into a +stream+.
58
83
  #
@@ -65,61 +90,97 @@ class SaferGenerator
65
90
  end
66
91
  # Creates the pipe for communicating with the block.
67
92
  rd,wr = IO.pipe
68
- # Creates a process for executing the block.
69
- pid = fork
70
- if pid then
71
- # This is the parent: waits for the block execution result.
72
- # No need to write on the pipe. close it.
73
- wr.close
74
- # Read the result of the process and send it to stream
75
- until rd.eof?
76
- stream << rd.read
77
- end
78
- # No more need of rd.
79
- rd.close
80
- # Wait the end of the child process
81
- Process.wait(pid)
82
- # Where there a trouble?
83
- unless $?.exited? then
84
- # pid did not exit, internal error.
85
- raise "*Internal error*: safer process #{pid} did not exit."
86
- end
87
- if $?.exitstatus !=0 then
88
- # Reconstruct the exception from the stream, the exit
89
- # status is the number of line to use.
90
- e0 = Marshal.load( stream.string.each_line.
91
- to_a[-$?.exitstatus..-1].join )
92
- # Then resend the eception encapsulated into another one
93
- # telling the safer process failed.
94
- begin
95
- raise e0
96
- rescue Exception => e1
97
- raise SaferException.new("*Error*: exception occured in safer process #{pid}.")
98
- end
99
- end
100
- else
101
- # This is the child: enter in safe mode and execute the block.
102
- # No need to write on the pipe. close it.
103
- rd.close
104
- # Secure.
105
- secure
106
- # Execute the block.
93
+ # # Creates a process for executing the block.
94
+ # pid = fork
95
+ # if pid then
96
+ # # This is the parent: waits for the block execution result.
97
+ # # No need to write on the pipe. close it.
98
+ # wr.close
99
+ # # Read the result of the process and send it to stream
100
+ # until rd.eof?
101
+ # stream << rd.read
102
+ # end
103
+ # # No more need of rd.
104
+ # rd.close
105
+ # # Wait the end of the child process
106
+ # Process.wait(pid)
107
+ # # Where there a trouble?
108
+ # unless $?.exited? then
109
+ # # pid did not exit, internal error.
110
+ # raise "*Internal error*: safer process #{pid} did not exit."
111
+ # end
112
+ # if $?.exitstatus !=0 then
113
+ # # Reconstruct the exception from the stream, the exit
114
+ # # status is the number of line to use.
115
+ # e0 = Marshal.load( stream.string.each_line.
116
+ # to_a[-$?.exitstatus..-1].join )
117
+ # # Then resend the eception encapsulated into another one
118
+ # # telling the safer process failed.
119
+ # begin
120
+ # raise e0
121
+ # rescue Exception => e1
122
+ # raise SaferException.new("*Error*: exception occured in safer process #{pid}.")
123
+ # end
124
+ # end
125
+ # else
126
+ # # This is the child: enter in safe mode and execute the block.
127
+ # # No need to write on the pipe. close it.
128
+ # rd.close
129
+ # # Secure.
130
+ # secure
131
+ # # Execute the block.
132
+ # begin
133
+ # block.call(wr)
134
+ # rescue Exception => e
135
+ # # The exception is serialized and passed to the main process
136
+ # # through the pipe.
137
+ # e = Marshal.dump(e)
138
+ # wr << "\n" << e
139
+ # # The exit status is the number of line of the serialized
140
+ # # exception.
141
+ # exit!(e.each_line.count)
142
+ # end
143
+ # # No more need of wr.
144
+ # wr.close
145
+ # # End the process without any error.
146
+ # exit!(0)
147
+ # end
148
+ #
149
+ # # Is there a string to return?
150
+ # if to_return then
151
+ # return stream.string
152
+ # else
153
+ # return nil
154
+ # end
155
+
156
+ # Secure.
157
+ secure
158
+ trouble = nil
159
+ # Execute the block.
160
+ begin
161
+ block.call(wr)
162
+ rescue Exception => e
163
+ trouble = e
164
+ end
165
+ # No more need of wr.
166
+ wr.close
167
+
168
+ # Unsecure and process the result.
169
+ unsecure
170
+ # Read the result of the process and send it to stream
171
+ until rd.eof?
172
+ stream << rd.read
173
+ end
174
+ # No more need of rd.
175
+ rd.close
176
+ if trouble then
107
177
  begin
108
- block.call(wr)
109
- rescue Exception => e
110
- # The exception is serialized and passed to the main process
111
- # through the pipe.
112
- e = Marshal.dump(e)
113
- wr << "\n" << e
114
- # The exit status is the number of line of the serialized
115
- # exception.
116
- exit!(e.each_line.count)
178
+ raise trouble
179
+ rescue Exception => e1
180
+ raise SaferException.new("*Error*: exception occured in safe mode.")
117
181
  end
118
- # No more need of wr.
119
- wr.close
120
- # End the process without any error.
121
- exit!(0)
122
182
  end
183
+
123
184
  # Is there a string to return?
124
185
  if to_return then
125
186
  return stream.string
data/lib/ppr/test_ppr.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  ######################################################################
4
4
 
5
5
  require "ppr.rb"
6
+ require 'stringio'
6
7
 
7
8
  # Function for testing a preprocessor
8
9
  def test_preprocessor(preprocessor,input,expected)
@@ -149,7 +150,7 @@ $success &= test_preprocessor_exception($ppr,
149
150
  print "... Undefined symbol in macro code... "
150
151
  $success &= test_preprocessor_exception($ppr,
151
152
  "\n.def HE(name)\n :< foobar \n.end\nHE(Foo)",
152
- "HE:5):2: undefined local variable or method")
153
+ "HE:5):3: undefined local variable or method")
153
154
 
154
155
 
155
156
  # puts "\nBuilding a preprocessor with an invalid escape character."
data/lib/ppr/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ppr
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.8"
3
3
  end
data/ppr.gemspec CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
34
34
  spec.require_paths = ["lib"]
35
35
 
36
- spec.add_development_dependency "bundler", "~> 1.14"
37
- spec.add_development_dependency "rake", "~> 10.0"
38
- spec.add_development_dependency "minitest", "~> 5.0"
36
+ spec.add_development_dependency "bundler", ">= 2.2.10"
37
+ spec.add_development_dependency "rake", ">= 12.3.3"
38
+ spec.add_development_dependency "minitest", ">= 12.3.3"
39
39
  end
metadata CHANGED
@@ -1,57 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ppr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lovic Gauthier
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-16 00:00:00.000000000 Z
11
+ date: 2022-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.14'
19
+ version: 2.2.10
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.14'
26
+ version: 2.2.10
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '5.0'
47
+ version: 12.3.3
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '5.0'
54
+ version: 12.3.3
55
55
  description: |-
56
56
  Preprocessor in Ruby: provides a Ruby class named Rpp which implements a text preprocessor where macros are specified in Ruby language.
57
57
  Usage:
@@ -90,7 +90,7 @@ homepage: https://github.com/civol
90
90
  licenses:
91
91
  - MIT
92
92
  metadata: {}
93
- post_install_message:
93
+ post_install_message:
94
94
  rdoc_options: []
95
95
  require_paths:
96
96
  - lib
@@ -105,9 +105,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
105
  - !ruby/object:Gem::Version
106
106
  version: '0'
107
107
  requirements: []
108
- rubyforge_project:
109
- rubygems_version: 2.6.8
110
- signing_key:
108
+ rubygems_version: 3.0.8
109
+ signing_key:
111
110
  specification_version: 4
112
111
  summary: 'Preprocessor in Ruby: text preprocessor where macros are specified in Ruby
113
112
  language.'