laser 0.7.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (319) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +14 -0
  4. data/LICENSE +661 -0
  5. data/README.md +158 -0
  6. data/Rakefile +104 -0
  7. data/VERSION +1 -0
  8. data/bin/laser +7 -0
  9. data/design_docs/goals.md +57 -0
  10. data/design_docs/object_regex.md +426 -0
  11. data/design_docs/type_annotations.md +80 -0
  12. data/ext/laser/BasicBlock.cpp +572 -0
  13. data/ext/laser/BasicBlock.h +118 -0
  14. data/ext/laser/extconf.rb +3 -0
  15. data/features/laser.feature +25 -0
  16. data/features/step_definitions/laser_steps.rb +39 -0
  17. data/features/support/env.rb +14 -0
  18. data/features/support/testdata/1_input +1 -0
  19. data/features/support/testdata/1_output +1 -0
  20. data/features/support/testdata/2_input +4 -0
  21. data/features/support/testdata/2_output +4 -0
  22. data/features/support/testdata/3_input +8 -0
  23. data/features/support/testdata/3_output +11 -0
  24. data/features/support/testdata/4_input +5 -0
  25. data/features/support/testdata/4_output +5 -0
  26. data/features/support/testdata/5_input +13 -0
  27. data/laser.gemspec +382 -0
  28. data/lib/laser.rb +98 -0
  29. data/lib/laser/analysis/annotations.rb +95 -0
  30. data/lib/laser/analysis/annotations/annotation_config.yaml +3 -0
  31. data/lib/laser/analysis/annotations/comment_attachment_annotation.rb +66 -0
  32. data/lib/laser/analysis/annotations/node_pointers_annotation.rb +36 -0
  33. data/lib/laser/analysis/annotations/runtime_annotation.rb +55 -0
  34. data/lib/laser/analysis/argument_expansion.rb +132 -0
  35. data/lib/laser/analysis/arity.rb +34 -0
  36. data/lib/laser/analysis/bindings.rb +144 -0
  37. data/lib/laser/analysis/bootstrap/bootstrap.rb +298 -0
  38. data/lib/laser/analysis/bootstrap/laser_class.rb +106 -0
  39. data/lib/laser/analysis/bootstrap/laser_method.rb +255 -0
  40. data/lib/laser/analysis/bootstrap/laser_module.rb +403 -0
  41. data/lib/laser/analysis/bootstrap/laser_module_copy.rb +74 -0
  42. data/lib/laser/analysis/bootstrap/laser_object.rb +69 -0
  43. data/lib/laser/analysis/bootstrap/laser_proc.rb +150 -0
  44. data/lib/laser/analysis/bootstrap/laser_singleton_class.rb +44 -0
  45. data/lib/laser/analysis/comments.rb +35 -0
  46. data/lib/laser/analysis/control_flow.rb +28 -0
  47. data/lib/laser/analysis/control_flow/alias_analysis.rb +31 -0
  48. data/lib/laser/analysis/control_flow/basic_block.rb +105 -0
  49. data/lib/laser/analysis/control_flow/cfg_builder.rb +2505 -0
  50. data/lib/laser/analysis/control_flow/cfg_instruction.rb +190 -0
  51. data/lib/laser/analysis/control_flow/constant_propagation.rb +742 -0
  52. data/lib/laser/analysis/control_flow/control_flow_graph.rb +370 -0
  53. data/lib/laser/analysis/control_flow/lifetime_analysis.rb +91 -0
  54. data/lib/laser/analysis/control_flow/method_call_search.rb +26 -0
  55. data/lib/laser/analysis/control_flow/raise_properties.rb +25 -0
  56. data/lib/laser/analysis/control_flow/simulation.rb +385 -0
  57. data/lib/laser/analysis/control_flow/static_single_assignment.rb +185 -0
  58. data/lib/laser/analysis/control_flow/unreachability_analysis.rb +57 -0
  59. data/lib/laser/analysis/control_flow/unused_variables.rb +91 -0
  60. data/lib/laser/analysis/control_flow/yield_properties.rb +103 -0
  61. data/lib/laser/analysis/errors.rb +131 -0
  62. data/lib/laser/analysis/laser_utils.rb +18 -0
  63. data/lib/laser/analysis/lexical_analysis.rb +172 -0
  64. data/lib/laser/analysis/method_call.rb +68 -0
  65. data/lib/laser/analysis/protocol_registry.rb +30 -0
  66. data/lib/laser/analysis/scope.rb +118 -0
  67. data/lib/laser/analysis/sexp.rb +159 -0
  68. data/lib/laser/analysis/sexp_analysis.rb +40 -0
  69. data/lib/laser/analysis/sexp_extensions/constant_extraction.rb +115 -0
  70. data/lib/laser/analysis/sexp_extensions/source_location.rb +164 -0
  71. data/lib/laser/analysis/sexp_extensions/type_inference.rb +47 -0
  72. data/lib/laser/analysis/signature.rb +76 -0
  73. data/lib/laser/analysis/special_methods/send.rb +67 -0
  74. data/lib/laser/analysis/unused_methods.rb +21 -0
  75. data/lib/laser/analysis/visitor.rb +141 -0
  76. data/lib/laser/annotation_parser/annotations.treetop +126 -0
  77. data/lib/laser/annotation_parser/annotations_parser.rb +748 -0
  78. data/lib/laser/annotation_parser/class_annotations.treetop +82 -0
  79. data/lib/laser/annotation_parser/class_annotations_parser.rb +654 -0
  80. data/lib/laser/annotation_parser/overload.treetop +24 -0
  81. data/lib/laser/annotation_parser/overload_parser.rb +167 -0
  82. data/lib/laser/annotation_parser/parsers.rb +6 -0
  83. data/lib/laser/annotation_parser/structural.treetop +37 -0
  84. data/lib/laser/annotation_parser/structural_parser.rb +406 -0
  85. data/lib/laser/annotation_parser/useful_parsers.treetop +47 -0
  86. data/lib/laser/annotation_parser/useful_parsers_parser.rb +674 -0
  87. data/lib/laser/rake/task.rb +46 -0
  88. data/lib/laser/runner.rb +189 -0
  89. data/lib/laser/scanner.rb +169 -0
  90. data/lib/laser/standard_library/_thread.rb +110 -0
  91. data/lib/laser/standard_library/abbrev.rb +103 -0
  92. data/lib/laser/standard_library/array.rb +418 -0
  93. data/lib/laser/standard_library/base64.rb +91 -0
  94. data/lib/laser/standard_library/basic_object.rb +55 -0
  95. data/lib/laser/standard_library/benchmark.rb +556 -0
  96. data/lib/laser/standard_library/bignum.rb +185 -0
  97. data/lib/laser/standard_library/cgi.rb +275 -0
  98. data/lib/laser/standard_library/cgi/cookie.rb +147 -0
  99. data/lib/laser/standard_library/cgi/core.rb +791 -0
  100. data/lib/laser/standard_library/cgi/html.rb +1021 -0
  101. data/lib/laser/standard_library/cgi/session.rb +537 -0
  102. data/lib/laser/standard_library/cgi/session/pstore.rb +111 -0
  103. data/lib/laser/standard_library/cgi/util.rb +188 -0
  104. data/lib/laser/standard_library/class_definitions.rb +333 -0
  105. data/lib/laser/standard_library/comparable.rb +125 -0
  106. data/lib/laser/standard_library/complex.rb +162 -0
  107. data/lib/laser/standard_library/enumerable.rb +178 -0
  108. data/lib/laser/standard_library/exceptions.rb +135 -0
  109. data/lib/laser/standard_library/fixnum.rb +188 -0
  110. data/lib/laser/standard_library/float.rb +180 -0
  111. data/lib/laser/standard_library/hash.rb +237 -0
  112. data/lib/laser/standard_library/integer.rb +123 -0
  113. data/lib/laser/standard_library/laser_magic.rb +7 -0
  114. data/lib/laser/standard_library/nil_false_true.rb +113 -0
  115. data/lib/laser/standard_library/numbers.rb +192 -0
  116. data/lib/laser/standard_library/proc.rb +31 -0
  117. data/lib/laser/standard_library/set.rb +1348 -0
  118. data/lib/laser/standard_library/string.rb +666 -0
  119. data/lib/laser/standard_library/stringio.rb +2 -0
  120. data/lib/laser/standard_library/symbol.rb +125 -0
  121. data/lib/laser/standard_library/tsort.rb +242 -0
  122. data/lib/laser/support/acts_as_struct.rb +66 -0
  123. data/lib/laser/support/frequency.rb +55 -0
  124. data/lib/laser/support/inheritable_attributes.rb +145 -0
  125. data/lib/laser/support/module_extensions.rb +94 -0
  126. data/lib/laser/support/placeholder_object.rb +13 -0
  127. data/lib/laser/third_party/rgl/adjacency.rb +221 -0
  128. data/lib/laser/third_party/rgl/base.rb +228 -0
  129. data/lib/laser/third_party/rgl/bidirectional.rb +39 -0
  130. data/lib/laser/third_party/rgl/condensation.rb +47 -0
  131. data/lib/laser/third_party/rgl/connected_components.rb +138 -0
  132. data/lib/laser/third_party/rgl/control_flow.rb +170 -0
  133. data/lib/laser/third_party/rgl/depth_first_spanning_tree.rb +37 -0
  134. data/lib/laser/third_party/rgl/dominators.rb +124 -0
  135. data/lib/laser/third_party/rgl/dot.rb +93 -0
  136. data/lib/laser/third_party/rgl/graphxml.rb +51 -0
  137. data/lib/laser/third_party/rgl/implicit.rb +174 -0
  138. data/lib/laser/third_party/rgl/mutable.rb +117 -0
  139. data/lib/laser/third_party/rgl/rdot.rb +445 -0
  140. data/lib/laser/third_party/rgl/topsort.rb +72 -0
  141. data/lib/laser/third_party/rgl/transitivity.rb +180 -0
  142. data/lib/laser/third_party/rgl/traversal.rb +348 -0
  143. data/lib/laser/types/types.rb +433 -0
  144. data/lib/laser/version.rb +14 -0
  145. data/lib/laser/warning.rb +149 -0
  146. data/lib/laser/warning_sets/default.yml +13 -0
  147. data/lib/laser/warnings/assignment_in_condition.rb +20 -0
  148. data/lib/laser/warnings/comment_spacing.rb +31 -0
  149. data/lib/laser/warnings/extra_blank_lines.rb +30 -0
  150. data/lib/laser/warnings/extra_whitespace.rb +16 -0
  151. data/lib/laser/warnings/hash_symbol_18_warning.rb +63 -0
  152. data/lib/laser/warnings/hash_symbol_19_warning.rb +29 -0
  153. data/lib/laser/warnings/line_length.rb +115 -0
  154. data/lib/laser/warnings/misaligned_unindentation.rb +17 -0
  155. data/lib/laser/warnings/operator_spacing.rb +68 -0
  156. data/lib/laser/warnings/parens_on_declaration.rb +30 -0
  157. data/lib/laser/warnings/rescue_exception.rb +42 -0
  158. data/lib/laser/warnings/semicolon.rb +25 -0
  159. data/lib/laser/warnings/sexp_errors.rb +24 -0
  160. data/lib/laser/warnings/uncalled_method_warning.rb +7 -0
  161. data/lib/laser/warnings/useless_double_quotes.rb +38 -0
  162. data/spec/analysis_specs/annotations_spec.rb +47 -0
  163. data/spec/analysis_specs/annotations_specs/comment_attachment_spec.rb +68 -0
  164. data/spec/analysis_specs/annotations_specs/node_pointers_annotation_spec.rb +90 -0
  165. data/spec/analysis_specs/annotations_specs/runtime_annotation_spec.rb +135 -0
  166. data/spec/analysis_specs/annotations_specs/spec_helper.rb +33 -0
  167. data/spec/analysis_specs/argument_expansion_spec.rb +113 -0
  168. data/spec/analysis_specs/bindings_spec.rb +36 -0
  169. data/spec/analysis_specs/comment_spec.rb +93 -0
  170. data/spec/analysis_specs/control_flow_specs/cfg_instruction_spec.rb +111 -0
  171. data/spec/analysis_specs/control_flow_specs/constant_propagation_spec.rb +560 -0
  172. data/spec/analysis_specs/control_flow_specs/control_flow_graph_spec.rb +5 -0
  173. data/spec/analysis_specs/control_flow_specs/raise_properties_spec.rb +310 -0
  174. data/spec/analysis_specs/control_flow_specs/raise_type_inference_spec.rb +301 -0
  175. data/spec/analysis_specs/control_flow_specs/return_type_inference_spec.rb +431 -0
  176. data/spec/analysis_specs/control_flow_specs/simulation_spec.rb +158 -0
  177. data/spec/analysis_specs/control_flow_specs/spec_helper.rb +110 -0
  178. data/spec/analysis_specs/control_flow_specs/tuple_misuse_inference_spec.rb +125 -0
  179. data/spec/analysis_specs/control_flow_specs/unreachability_analysis_spec.rb +76 -0
  180. data/spec/analysis_specs/control_flow_specs/unused_variable_spec.rb +99 -0
  181. data/spec/analysis_specs/control_flow_specs/yield_properties_spec.rb +372 -0
  182. data/spec/analysis_specs/error_spec.rb +30 -0
  183. data/spec/analysis_specs/laser_class_spec.rb +322 -0
  184. data/spec/analysis_specs/lexical_analysis_spec.rb +184 -0
  185. data/spec/analysis_specs/protocol_registry_spec.rb +63 -0
  186. data/spec/analysis_specs/scope_annotation_spec.rb +1013 -0
  187. data/spec/analysis_specs/scope_spec.rb +126 -0
  188. data/spec/analysis_specs/sexp_analysis_spec.rb +30 -0
  189. data/spec/analysis_specs/sexp_extension_specs/constant_extraction_spec.rb +309 -0
  190. data/spec/analysis_specs/sexp_extension_specs/source_location_spec.rb +231 -0
  191. data/spec/analysis_specs/sexp_extension_specs/spec_helper.rb +1 -0
  192. data/spec/analysis_specs/sexp_extension_specs/type_inference_spec.rb +252 -0
  193. data/spec/analysis_specs/sexp_spec.rb +167 -0
  194. data/spec/analysis_specs/spec_helper.rb +27 -0
  195. data/spec/analysis_specs/unused_methods_spec.rb +65 -0
  196. data/spec/analysis_specs/visitor_spec.rb +64 -0
  197. data/spec/annotation_parser_specs/annotations_parser_spec.rb +89 -0
  198. data/spec/annotation_parser_specs/class_annotation_parser_spec.rb +120 -0
  199. data/spec/annotation_parser_specs/overload_parser_spec.rb +39 -0
  200. data/spec/annotation_parser_specs/parsers_spec.rb +14 -0
  201. data/spec/annotation_parser_specs/spec_helper.rb +1 -0
  202. data/spec/annotation_parser_specs/structural_parser_spec.rb +67 -0
  203. data/spec/laser_spec.rb +14 -0
  204. data/spec/rake_specs/spec_helper.rb +1 -0
  205. data/spec/rake_specs/task_spec.rb +67 -0
  206. data/spec/runner_spec.rb +207 -0
  207. data/spec/scanner_spec.rb +75 -0
  208. data/spec/spec_helper.rb +121 -0
  209. data/spec/standard_library/exceptions_spec.rb +19 -0
  210. data/spec/standard_library/globals_spec.rb +14 -0
  211. data/spec/standard_library/set_spec.rb +31 -0
  212. data/spec/standard_library/spec_helper.rb +1 -0
  213. data/spec/standard_library/standard_library_spec.rb +302 -0
  214. data/spec/support_specs/acts_as_struct_spec.rb +94 -0
  215. data/spec/support_specs/frequency_spec.rb +23 -0
  216. data/spec/support_specs/module_extensions_spec.rb +117 -0
  217. data/spec/support_specs/spec_helper.rb +1 -0
  218. data/spec/type_specs/spec_helper.rb +1 -0
  219. data/spec/type_specs/types_spec.rb +133 -0
  220. data/spec/warning_spec.rb +95 -0
  221. data/spec/warning_specs/assignment_in_condition_spec.rb +68 -0
  222. data/spec/warning_specs/comment_spacing_spec.rb +65 -0
  223. data/spec/warning_specs/extra_blank_lines_spec.rb +70 -0
  224. data/spec/warning_specs/extra_whitespace_spec.rb +33 -0
  225. data/spec/warning_specs/hash_symbol_18_warning_spec.rb +89 -0
  226. data/spec/warning_specs/hash_symbol_19_warning_spec.rb +63 -0
  227. data/spec/warning_specs/line_length_spec.rb +173 -0
  228. data/spec/warning_specs/misaligned_unindentation_spec.rb +35 -0
  229. data/spec/warning_specs/operator_spacing_spec.rb +104 -0
  230. data/spec/warning_specs/parens_on_declaration_spec.rb +57 -0
  231. data/spec/warning_specs/rescue_exception_spec.rb +105 -0
  232. data/spec/warning_specs/semicolon_spec.rb +58 -0
  233. data/spec/warning_specs/spec_helper.rb +1 -0
  234. data/spec/warning_specs/useless_double_quotes_spec.rb +74 -0
  235. data/status_reports/2010/12/2010-12-14.md +163 -0
  236. data/status_reports/2010/12/2010-12-23.md +298 -0
  237. data/status_reports/2010/12/2010-12-24.md +6 -0
  238. data/test/third_party_tests/rgl_tests/TestComponents.rb +65 -0
  239. data/test/third_party_tests/rgl_tests/TestCycles.rb +61 -0
  240. data/test/third_party_tests/rgl_tests/TestDirectedGraph.rb +125 -0
  241. data/test/third_party_tests/rgl_tests/TestDot.rb +18 -0
  242. data/test/third_party_tests/rgl_tests/TestEdge.rb +34 -0
  243. data/test/third_party_tests/rgl_tests/TestGraph.rb +71 -0
  244. data/test/third_party_tests/rgl_tests/TestGraphXML.rb +57 -0
  245. data/test/third_party_tests/rgl_tests/TestImplicit.rb +52 -0
  246. data/test/third_party_tests/rgl_tests/TestRdot.rb +863 -0
  247. data/test/third_party_tests/rgl_tests/TestTransitivity.rb +129 -0
  248. data/test/third_party_tests/rgl_tests/TestTraversal.rb +220 -0
  249. data/test/third_party_tests/rgl_tests/TestUnDirectedGraph.rb +102 -0
  250. data/test/third_party_tests/rgl_tests/examples/north/Graph.log +128 -0
  251. data/test/third_party_tests/rgl_tests/examples/north/g.10.0.graphml +28 -0
  252. data/test/third_party_tests/rgl_tests/examples/north/g.10.1.graphml +28 -0
  253. data/test/third_party_tests/rgl_tests/examples/north/g.10.11.graphml +31 -0
  254. data/test/third_party_tests/rgl_tests/examples/north/g.10.12.graphml +27 -0
  255. data/test/third_party_tests/rgl_tests/examples/north/g.10.13.graphml +27 -0
  256. data/test/third_party_tests/rgl_tests/examples/north/g.10.14.graphml +27 -0
  257. data/test/third_party_tests/rgl_tests/examples/north/g.10.15.graphml +26 -0
  258. data/test/third_party_tests/rgl_tests/examples/north/g.10.16.graphml +26 -0
  259. data/test/third_party_tests/rgl_tests/examples/north/g.10.17.graphml +26 -0
  260. data/test/third_party_tests/rgl_tests/examples/north/g.10.19.graphml +37 -0
  261. data/test/third_party_tests/rgl_tests/examples/north/g.10.2.graphml +28 -0
  262. data/test/third_party_tests/rgl_tests/examples/north/g.10.20.graphml +38 -0
  263. data/test/third_party_tests/rgl_tests/examples/north/g.10.22.graphml +43 -0
  264. data/test/third_party_tests/rgl_tests/examples/north/g.10.24.graphml +30 -0
  265. data/test/third_party_tests/rgl_tests/examples/north/g.10.25.graphml +45 -0
  266. data/test/third_party_tests/rgl_tests/examples/north/g.10.27.graphml +38 -0
  267. data/test/third_party_tests/rgl_tests/examples/north/g.10.28.graphml +30 -0
  268. data/test/third_party_tests/rgl_tests/examples/north/g.10.29.graphml +38 -0
  269. data/test/third_party_tests/rgl_tests/examples/north/g.10.3.graphml +26 -0
  270. data/test/third_party_tests/rgl_tests/examples/north/g.10.30.graphml +34 -0
  271. data/test/third_party_tests/rgl_tests/examples/north/g.10.31.graphml +42 -0
  272. data/test/third_party_tests/rgl_tests/examples/north/g.10.34.graphml +42 -0
  273. data/test/third_party_tests/rgl_tests/examples/north/g.10.37.graphml +28 -0
  274. data/test/third_party_tests/rgl_tests/examples/north/g.10.38.graphml +38 -0
  275. data/test/third_party_tests/rgl_tests/examples/north/g.10.39.graphml +36 -0
  276. data/test/third_party_tests/rgl_tests/examples/north/g.10.4.graphml +26 -0
  277. data/test/third_party_tests/rgl_tests/examples/north/g.10.40.graphml +37 -0
  278. data/test/third_party_tests/rgl_tests/examples/north/g.10.41.graphml +37 -0
  279. data/test/third_party_tests/rgl_tests/examples/north/g.10.42.graphml +26 -0
  280. data/test/third_party_tests/rgl_tests/examples/north/g.10.45.graphml +28 -0
  281. data/test/third_party_tests/rgl_tests/examples/north/g.10.46.graphml +32 -0
  282. data/test/third_party_tests/rgl_tests/examples/north/g.10.5.graphml +31 -0
  283. data/test/third_party_tests/rgl_tests/examples/north/g.10.50.graphml +30 -0
  284. data/test/third_party_tests/rgl_tests/examples/north/g.10.56.graphml +29 -0
  285. data/test/third_party_tests/rgl_tests/examples/north/g.10.57.graphml +32 -0
  286. data/test/third_party_tests/rgl_tests/examples/north/g.10.58.graphml +32 -0
  287. data/test/third_party_tests/rgl_tests/examples/north/g.10.6.graphml +26 -0
  288. data/test/third_party_tests/rgl_tests/examples/north/g.10.60.graphml +32 -0
  289. data/test/third_party_tests/rgl_tests/examples/north/g.10.61.graphml +34 -0
  290. data/test/third_party_tests/rgl_tests/examples/north/g.10.62.graphml +34 -0
  291. data/test/third_party_tests/rgl_tests/examples/north/g.10.68.graphml +30 -0
  292. data/test/third_party_tests/rgl_tests/examples/north/g.10.69.graphml +32 -0
  293. data/test/third_party_tests/rgl_tests/examples/north/g.10.7.graphml +29 -0
  294. data/test/third_party_tests/rgl_tests/examples/north/g.10.70.graphml +26 -0
  295. data/test/third_party_tests/rgl_tests/examples/north/g.10.71.graphml +27 -0
  296. data/test/third_party_tests/rgl_tests/examples/north/g.10.72.graphml +28 -0
  297. data/test/third_party_tests/rgl_tests/examples/north/g.10.74.graphml +29 -0
  298. data/test/third_party_tests/rgl_tests/examples/north/g.10.75.graphml +29 -0
  299. data/test/third_party_tests/rgl_tests/examples/north/g.10.78.graphml +27 -0
  300. data/test/third_party_tests/rgl_tests/examples/north/g.10.79.graphml +34 -0
  301. data/test/third_party_tests/rgl_tests/examples/north/g.10.8.graphml +29 -0
  302. data/test/third_party_tests/rgl_tests/examples/north/g.10.80.graphml +34 -0
  303. data/test/third_party_tests/rgl_tests/examples/north/g.10.82.graphml +35 -0
  304. data/test/third_party_tests/rgl_tests/examples/north/g.10.83.graphml +32 -0
  305. data/test/third_party_tests/rgl_tests/examples/north/g.10.85.graphml +34 -0
  306. data/test/third_party_tests/rgl_tests/examples/north/g.10.86.graphml +34 -0
  307. data/test/third_party_tests/rgl_tests/examples/north/g.10.88.graphml +37 -0
  308. data/test/third_party_tests/rgl_tests/examples/north/g.10.89.graphml +29 -0
  309. data/test/third_party_tests/rgl_tests/examples/north/g.10.9.graphml +26 -0
  310. data/test/third_party_tests/rgl_tests/examples/north/g.10.90.graphml +32 -0
  311. data/test/third_party_tests/rgl_tests/examples/north/g.10.91.graphml +31 -0
  312. data/test/third_party_tests/rgl_tests/examples/north/g.10.92.graphml +26 -0
  313. data/test/third_party_tests/rgl_tests/examples/north/g.10.93.graphml +32 -0
  314. data/test/third_party_tests/rgl_tests/examples/north/g.10.94.graphml +34 -0
  315. data/test/third_party_tests/rgl_tests/examples/north/g.12.8.graphml +40 -0
  316. data/test/third_party_tests/rgl_tests/examples/north/g.14.9.graphml +36 -0
  317. data/test/third_party_tests/rgl_tests/test_helper.rb +7 -0
  318. data/test/third_party_tests/test_inheritable_attributes.rb +187 -0
  319. metadata +470 -0
@@ -0,0 +1,537 @@
1
+ #
2
+ # cgi/session.rb - session support for cgi scripts
3
+ #
4
+ # Copyright (C) 2001 Yukihiro "Matz" Matsumoto
5
+ # Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
6
+ # Copyright (C) 2000 Information-technology Promotion Agency, Japan
7
+ #
8
+ # Author: Yukihiro "Matz" Matsumoto
9
+ #
10
+ # Documentation: William Webber (william@williamwebber.com)
11
+ #
12
+ # == Overview
13
+ #
14
+ # This file provides the +CGI::Session+ class, which provides session
15
+ # support for CGI scripts. A session is a sequence of HTTP requests
16
+ # and responses linked together and associated with a single client.
17
+ # Information associated with the session is stored
18
+ # on the server between requests. A session id is passed between client
19
+ # and server with every request and response, transparently
20
+ # to the user. This adds state information to the otherwise stateless
21
+ # HTTP request/response protocol.
22
+ #
23
+ # See the documentation to the +CGI::Session+ class for more details
24
+ # and examples of usage. See cgi.rb for the +CGI+ class itself.
25
+
26
+ require 'cgi'
27
+ require 'tmpdir'
28
+
29
+ class CGI
30
+
31
+ # Class representing an HTTP session. See documentation for the file
32
+ # cgi/session.rb for an introduction to HTTP sessions.
33
+ #
34
+ # == Lifecycle
35
+ #
36
+ # A CGI::Session instance is created from a CGI object. By default,
37
+ # this CGI::Session instance will start a new session if none currently
38
+ # exists, or continue the current session for this client if one does
39
+ # exist. The +new_session+ option can be used to either always or
40
+ # never create a new session. See #new() for more details.
41
+ #
42
+ # #delete() deletes a session from session storage. It
43
+ # does not however remove the session id from the client. If the client
44
+ # makes another request with the same id, the effect will be to start
45
+ # a new session with the old session's id.
46
+ #
47
+ # == Setting and retrieving session data.
48
+ #
49
+ # The Session class associates data with a session as key-value pairs.
50
+ # This data can be set and retrieved by indexing the Session instance
51
+ # using '[]', much the same as hashes (although other hash methods
52
+ # are not supported).
53
+ #
54
+ # When session processing has been completed for a request, the
55
+ # session should be closed using the close() method. This will
56
+ # store the session's state to persistent storage. If you want
57
+ # to store the session's state to persistent storage without
58
+ # finishing session processing for this request, call the update()
59
+ # method.
60
+ #
61
+ # == Storing session state
62
+ #
63
+ # The caller can specify what form of storage to use for the session's
64
+ # data with the +database_manager+ option to CGI::Session::new. The
65
+ # following storage classes are provided as part of the standard library:
66
+ #
67
+ # CGI::Session::FileStore:: stores data as plain text in a flat file. Only
68
+ # works with String data. This is the default
69
+ # storage type.
70
+ # CGI::Session::MemoryStore:: stores data in an in-memory hash. The data
71
+ # only persists for as long as the current ruby
72
+ # interpreter instance does.
73
+ # CGI::Session::PStore:: stores data in Marshalled format. Provided by
74
+ # cgi/session/pstore.rb. Supports data of any type,
75
+ # and provides file-locking and transaction support.
76
+ #
77
+ # Custom storage types can also be created by defining a class with
78
+ # the following methods:
79
+ #
80
+ # new(session, options)
81
+ # restore # returns hash of session data.
82
+ # update
83
+ # close
84
+ # delete
85
+ #
86
+ # Changing storage type mid-session does not work. Note in particular
87
+ # that by default the FileStore and PStore session data files have the
88
+ # same name. If your application switches from one to the other without
89
+ # making sure that filenames will be different
90
+ # and clients still have old sessions lying around in cookies, then
91
+ # things will break nastily!
92
+ #
93
+ # == Maintaining the session id.
94
+ #
95
+ # Most session state is maintained on the server. However, a session
96
+ # id must be passed backwards and forwards between client and server
97
+ # to maintain a reference to this session state.
98
+ #
99
+ # The simplest way to do this is via cookies. The CGI::Session class
100
+ # provides transparent support for session id communication via cookies
101
+ # if the client has cookies enabled.
102
+ #
103
+ # If the client has cookies disabled, the session id must be included
104
+ # as a parameter of all requests sent by the client to the server. The
105
+ # CGI::Session class in conjunction with the CGI class will transparently
106
+ # add the session id as a hidden input field to all forms generated
107
+ # using the CGI#form() HTML generation method. No built-in support is
108
+ # provided for other mechanisms, such as URL re-writing. The caller is
109
+ # responsible for extracting the session id from the session_id
110
+ # attribute and manually encoding it in URLs and adding it as a hidden
111
+ # input to HTML forms created by other mechanisms. Also, session expiry
112
+ # is not automatically handled.
113
+ #
114
+ # == Examples of use
115
+ #
116
+ # === Setting the user's name
117
+ #
118
+ # require 'cgi'
119
+ # require 'cgi/session'
120
+ # require 'cgi/session/pstore' # provides CGI::Session::PStore
121
+ #
122
+ # cgi = CGI.new("html4")
123
+ #
124
+ # session = CGI::Session.new(cgi,
125
+ # 'database_manager' => CGI::Session::PStore, # use PStore
126
+ # 'session_key' => '_rb_sess_id', # custom session key
127
+ # 'session_expires' => Time.now + 30 * 60, # 30 minute timeout
128
+ # 'prefix' => 'pstore_sid_') # PStore option
129
+ # if cgi.has_key?('user_name') and cgi['user_name'] != ''
130
+ # # coerce to String: cgi[] returns the
131
+ # # string-like CGI::QueryExtension::Value
132
+ # session['user_name'] = cgi['user_name'].to_s
133
+ # elsif !session['user_name']
134
+ # session['user_name'] = "guest"
135
+ # end
136
+ # session.close
137
+ #
138
+ # === Creating a new session safely
139
+ #
140
+ # require 'cgi'
141
+ # require 'cgi/session'
142
+ #
143
+ # cgi = CGI.new("html4")
144
+ #
145
+ # # We make sure to delete an old session if one exists,
146
+ # # not just to free resources, but to prevent the session
147
+ # # from being maliciously hijacked later on.
148
+ # begin
149
+ # session = CGI::Session.new(cgi, 'new_session' => false)
150
+ # session.delete
151
+ # rescue ArgumentError # if no old session
152
+ # end
153
+ # session = CGI::Session.new(cgi, 'new_session' => true)
154
+ # session.close
155
+ #
156
+ class Session
157
+
158
+ class NoSession < RuntimeError #:nodoc:
159
+ end
160
+
161
+ # The id of this session.
162
+ attr_reader :session_id, :new_session
163
+
164
+ def Session::callback(dbman) #:nodoc:
165
+ Proc.new{
166
+ dbman[0].close unless dbman.empty?
167
+ }
168
+ end
169
+
170
+ # Create a new session id.
171
+ #
172
+ # The session id is an MD5 hash based upon the time,
173
+ # a random number, and a constant string. This routine
174
+ # is used internally for automatically generated
175
+ # session ids.
176
+ def create_new_id
177
+ require 'securerandom'
178
+ begin
179
+ session_id = SecureRandom.hex(16)
180
+ rescue NotImplementedError
181
+ require 'digest/md5'
182
+ md5 = Digest::MD5::new
183
+ now = Time::now
184
+ md5.update(now.to_s)
185
+ md5.update(String(now.usec))
186
+ md5.update(String(rand(0)))
187
+ md5.update(String($$))
188
+ md5.update('foobar')
189
+ session_id = md5.hexdigest
190
+ end
191
+ session_id
192
+ end
193
+ private :create_new_id
194
+
195
+ # Create a new CGI::Session object for +request+.
196
+ #
197
+ # +request+ is an instance of the +CGI+ class (see cgi.rb).
198
+ # +option+ is a hash of options for initialising this
199
+ # CGI::Session instance. The following options are
200
+ # recognised:
201
+ #
202
+ # session_key:: the parameter name used for the session id.
203
+ # Defaults to '_session_id'.
204
+ # session_id:: the session id to use. If not provided, then
205
+ # it is retrieved from the +session_key+ parameter
206
+ # of the request, or automatically generated for
207
+ # a new session.
208
+ # new_session:: if true, force creation of a new session. If not set,
209
+ # a new session is only created if none currently
210
+ # exists. If false, a new session is never created,
211
+ # and if none currently exists and the +session_id+
212
+ # option is not set, an ArgumentError is raised.
213
+ # database_manager:: the name of the class providing storage facilities
214
+ # for session state persistence. Built-in support
215
+ # is provided for +FileStore+ (the default),
216
+ # +MemoryStore+, and +PStore+ (from
217
+ # cgi/session/pstore.rb). See the documentation for
218
+ # these classes for more details.
219
+ #
220
+ # The following options are also recognised, but only apply if the
221
+ # session id is stored in a cookie.
222
+ #
223
+ # session_expires:: the time the current session expires, as a
224
+ # +Time+ object. If not set, the session will terminate
225
+ # when the user's browser is closed.
226
+ # session_domain:: the hostname domain for which this session is valid.
227
+ # If not set, defaults to the hostname of the server.
228
+ # session_secure:: if +true+, this session will only work over HTTPS.
229
+ # session_path:: the path for which this session applies. Defaults
230
+ # to the directory of the CGI script.
231
+ #
232
+ # +option+ is also passed on to the session storage class initializer; see
233
+ # the documentation for each session storage class for the options
234
+ # they support.
235
+ #
236
+ # The retrieved or created session is automatically added to +request+
237
+ # as a cookie, and also to its +output_hidden+ table, which is used
238
+ # to add hidden input elements to forms.
239
+ #
240
+ # *WARNING* the +output_hidden+
241
+ # fields are surrounded by a <fieldset> tag in HTML 4 generation, which
242
+ # is _not_ invisible on many browsers; you may wish to disable the
243
+ # use of fieldsets with code similar to the following
244
+ # (see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37805)
245
+ #
246
+ # cgi = CGI.new("html4")
247
+ # class << cgi
248
+ # undef_method :fieldset
249
+ # end
250
+ #
251
+ def initialize(request, option={})
252
+ @new_session = false
253
+ session_key = option['session_key'] || '_session_id'
254
+ session_id = option['session_id']
255
+ unless session_id
256
+ if option['new_session']
257
+ session_id = create_new_id
258
+ @new_session = true
259
+ end
260
+ end
261
+ unless session_id
262
+ if request.key?(session_key)
263
+ session_id = request[session_key]
264
+ session_id = session_id.read if session_id.respond_to?(:read)
265
+ end
266
+ unless session_id
267
+ session_id, = request.cookies[session_key]
268
+ end
269
+ unless session_id
270
+ unless option.fetch('new_session', true)
271
+ raise ArgumentError, "session_key `%s' should be supplied"%session_key
272
+ end
273
+ session_id = create_new_id
274
+ @new_session = true
275
+ end
276
+ end
277
+ @session_id = session_id
278
+ dbman = option['database_manager'] || FileStore
279
+ begin
280
+ @dbman = dbman::new(self, option)
281
+ rescue NoSession
282
+ unless option.fetch('new_session', true)
283
+ raise ArgumentError, "invalid session_id `%s'"%session_id
284
+ end
285
+ session_id = @session_id = create_new_id unless session_id
286
+ @new_session=true
287
+ retry
288
+ end
289
+ request.instance_eval do
290
+ @output_hidden = {session_key => session_id} unless option['no_hidden']
291
+ @output_cookies = [
292
+ Cookie::new("name" => session_key,
293
+ "value" => session_id,
294
+ "expires" => option['session_expires'],
295
+ "domain" => option['session_domain'],
296
+ "secure" => option['session_secure'],
297
+ "path" =>
298
+ if option['session_path']
299
+ option['session_path']
300
+ elsif ENV["SCRIPT_NAME"]
301
+ File::dirname(ENV["SCRIPT_NAME"])
302
+ else
303
+ ""
304
+ end)
305
+ ] unless option['no_cookies']
306
+ end
307
+ @dbprot = [@dbman]
308
+ ObjectSpace::define_finalizer(self, Session::callback(@dbprot))
309
+ end
310
+
311
+ # Retrieve the session data for key +key+.
312
+ def [](key)
313
+ @data ||= @dbman.restore
314
+ @data[key]
315
+ end
316
+
317
+ # Set the session date for key +key+.
318
+ def []=(key, val)
319
+ @write_lock ||= true
320
+ @data ||= @dbman.restore
321
+ @data[key] = val
322
+ end
323
+
324
+ # Store session data on the server. For some session storage types,
325
+ # this is a no-op.
326
+ def update
327
+ @dbman.update
328
+ end
329
+
330
+ # Store session data on the server and close the session storage.
331
+ # For some session storage types, this is a no-op.
332
+ def close
333
+ @dbman.close
334
+ @dbprot.clear
335
+ end
336
+
337
+ # Delete the session from storage. Also closes the storage.
338
+ #
339
+ # Note that the session's data is _not_ automatically deleted
340
+ # upon the session expiring.
341
+ def delete
342
+ @dbman.delete
343
+ @dbprot.clear
344
+ end
345
+
346
+ # File-based session storage class.
347
+ #
348
+ # Implements session storage as a flat file of 'key=value' values.
349
+ # This storage type only works directly with String values; the
350
+ # user is responsible for converting other types to Strings when
351
+ # storing and from Strings when retrieving.
352
+ class FileStore
353
+ # Create a new FileStore instance.
354
+ #
355
+ # This constructor is used internally by CGI::Session. The
356
+ # user does not generally need to call it directly.
357
+ #
358
+ # +session+ is the session for which this instance is being
359
+ # created. The session id must only contain alphanumeric
360
+ # characters; automatically generated session ids observe
361
+ # this requirement.
362
+ #
363
+ # +option+ is a hash of options for the initializer. The
364
+ # following options are recognised:
365
+ #
366
+ # tmpdir:: the directory to use for storing the FileStore
367
+ # file. Defaults to Dir::tmpdir (generally "/tmp"
368
+ # on Unix systems).
369
+ # prefix:: the prefix to add to the session id when generating
370
+ # the filename for this session's FileStore file.
371
+ # Defaults to "cgi_sid_".
372
+ # suffix:: the prefix to add to the session id when generating
373
+ # the filename for this session's FileStore file.
374
+ # Defaults to the empty string.
375
+ #
376
+ # This session's FileStore file will be created if it does
377
+ # not exist, or opened if it does.
378
+ def initialize(session, option={})
379
+ dir = option['tmpdir'] || Dir::tmpdir
380
+ prefix = option['prefix'] || 'cgi_sid_'
381
+ suffix = option['suffix'] || ''
382
+ id = session.session_id
383
+ require 'digest/md5'
384
+ md5 = Digest::MD5.hexdigest(id)[0,16]
385
+ @path = dir+"/"+prefix+md5+suffix
386
+ if File::exist? @path
387
+ @hash = nil
388
+ else
389
+ unless session.new_session
390
+ raise CGI::Session::NoSession, "uninitialized session"
391
+ end
392
+ @hash = {}
393
+ end
394
+ end
395
+
396
+ # Restore session state from the session's FileStore file.
397
+ #
398
+ # Returns the session state as a hash.
399
+ def restore
400
+ unless @hash
401
+ @hash = {}
402
+ begin
403
+ lockf = File.open(@path+".lock", "r")
404
+ lockf.flock File::LOCK_SH
405
+ f = File.open(@path, 'r')
406
+ for line in f
407
+ line.chomp!
408
+ k, v = line.split('=',2)
409
+ @hash[CGI::unescape(k)] = Marshal.restore(CGI::unescape(v))
410
+ end
411
+ ensure
412
+ f.close unless f.nil?
413
+ lockf.close if lockf
414
+ end
415
+ end
416
+ @hash
417
+ end
418
+
419
+ # Save session state to the session's FileStore file.
420
+ def update
421
+ return unless @hash
422
+ begin
423
+ lockf = File.open(@path+".lock", File::CREAT|File::RDWR, 0600)
424
+ lockf.flock File::LOCK_EX
425
+ f = File.open(@path+".new", File::CREAT|File::TRUNC|File::WRONLY, 0600)
426
+ for k,v in @hash
427
+ f.printf "%s=%s\n", CGI::escape(k), CGI::escape(String(Marshal.dump(v)))
428
+ end
429
+ f.close
430
+ File.rename @path+".new", @path
431
+ ensure
432
+ f.close if f and !f.closed?
433
+ lockf.close if lockf
434
+ end
435
+ end
436
+
437
+ # Update and close the session's FileStore file.
438
+ def close
439
+ update
440
+ end
441
+
442
+ # Close and delete the session's FileStore file.
443
+ def delete
444
+ File::unlink @path+".lock" rescue nil
445
+ File::unlink @path+".new" rescue nil
446
+ File::unlink @path rescue Errno::ENOENT
447
+ end
448
+ end
449
+
450
+ # In-memory session storage class.
451
+ #
452
+ # Implements session storage as a global in-memory hash. Session
453
+ # data will only persist for as long as the ruby interpreter
454
+ # instance does.
455
+ class MemoryStore
456
+ GLOBAL_HASH_TABLE = {} #:nodoc:
457
+
458
+ # Create a new MemoryStore instance.
459
+ #
460
+ # +session+ is the session this instance is associated with.
461
+ # +option+ is a list of initialisation options. None are
462
+ # currently recognised.
463
+ def initialize(session, option=nil)
464
+ @session_id = session.session_id
465
+ unless GLOBAL_HASH_TABLE.key?(@session_id)
466
+ unless session.new_session
467
+ raise CGI::Session::NoSession, "uninitialized session"
468
+ end
469
+ GLOBAL_HASH_TABLE[@session_id] = {}
470
+ end
471
+ end
472
+
473
+ # Restore session state.
474
+ #
475
+ # Returns session data as a hash.
476
+ def restore
477
+ GLOBAL_HASH_TABLE[@session_id]
478
+ end
479
+
480
+ # Update session state.
481
+ #
482
+ # A no-op.
483
+ def update
484
+ # don't need to update; hash is shared
485
+ end
486
+
487
+ # Close session storage.
488
+ #
489
+ # A no-op.
490
+ def close
491
+ # don't need to close
492
+ end
493
+
494
+ # Delete the session state.
495
+ def delete
496
+ GLOBAL_HASH_TABLE.delete(@session_id)
497
+ end
498
+ end
499
+
500
+ # Dummy session storage class.
501
+ #
502
+ # Implements session storage place holder. No actual storage
503
+ # will be done.
504
+ class NullStore
505
+ # Create a new NullStore instance.
506
+ #
507
+ # +session+ is the session this instance is associated with.
508
+ # +option+ is a list of initialisation options. None are
509
+ # currently recognised.
510
+ def initialize(session, option=nil)
511
+ end
512
+
513
+ # Restore (empty) session state.
514
+ def restore
515
+ {}
516
+ end
517
+
518
+ # Update session state.
519
+ #
520
+ # A no-op.
521
+ def update
522
+ end
523
+
524
+ # Close session storage.
525
+ #
526
+ # A no-op.
527
+ def close
528
+ end
529
+
530
+ # Delete the session state.
531
+ #
532
+ # A no-op.
533
+ def delete
534
+ end
535
+ end
536
+ end
537
+ end