tdiary 5.5.0 → 5.6.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 (175) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +2 -0
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +37 -37
  5. data/doc/UPGRADE.md +1 -1
  6. data/lib/tdiary/admin.rb +11 -13
  7. data/lib/tdiary/application.rb +2 -7
  8. data/lib/tdiary/author_only_base.rb +78 -9
  9. data/lib/tdiary/base.rb +2 -2
  10. data/lib/tdiary/cgi_adapter.rb +7 -5
  11. data/lib/tdiary/cgi_compat.rb +27 -95
  12. data/lib/tdiary/configuration.rb +4 -0
  13. data/lib/tdiary/core_ext.rb +146 -1
  14. data/lib/tdiary/dispatcher/index_main.rb +5 -23
  15. data/lib/tdiary/dispatcher/update_main.rb +2 -17
  16. data/lib/tdiary/dispatcher.rb +29 -15
  17. data/lib/tdiary/filter/default.rb +2 -2
  18. data/lib/tdiary/filter/spam.rb +2 -2
  19. data/lib/tdiary/filter.rb +1 -1
  20. data/lib/tdiary/plugin/00default.rb +18 -3
  21. data/lib/tdiary/plugin/en/00default.rb +15 -0
  22. data/lib/tdiary/plugin/ja/00default.rb +15 -0
  23. data/lib/tdiary/plugin.rb +1 -1
  24. data/lib/tdiary/rack/error_handler.rb +36 -0
  25. data/lib/tdiary/rack.rb +1 -0
  26. data/lib/tdiary/request.rb +12 -2
  27. data/lib/tdiary/server.rb +25 -3
  28. data/lib/tdiary/version.rb +1 -1
  29. data/lib/tdiary/view.rb +33 -28
  30. data/lib/tdiary/view_helper.rb +10 -2
  31. data/lib/tdiary.rb +6 -1
  32. data/misc/plugin/image.rb +1 -1
  33. data/misc/plugin/makerss.rb +3 -3
  34. data/tdiary.conf.sample +8 -0
  35. data/tdiary.conf.sample-en +8 -0
  36. data/vendor/bundle/ruby/3.4.0/cache/net-imap-0.6.6.gem +0 -0
  37. data/vendor/bundle/ruby/3.4.0/cache/net-protocol-0.3.0.gem +0 -0
  38. data/vendor/bundle/ruby/3.4.0/cache/rack-3.2.7.gem +0 -0
  39. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/cgi-0.5.2/gem_make.out +5 -5
  40. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.5.1/gem_make.out +5 -5
  41. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/Gemfile +3 -4
  42. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/README.md +1 -1
  43. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.6.6/Rakefile +24 -0
  44. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/command_data.rb +62 -92
  45. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config/attr_accessors.rb +8 -9
  46. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config/attr_inheritance.rb +64 -1
  47. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config/attr_version_defaults.rb +1 -4
  48. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config.rb +209 -35
  49. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/connection_state.rb +1 -1
  50. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/data_encoding.rb +127 -27
  51. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.6.6/lib/net/imap/errors.rb +372 -0
  52. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/esearch_result.rb +6 -0
  53. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/response_data.rb +90 -11
  54. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/response_parser/parser_utils.rb +14 -23
  55. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/response_parser.rb +41 -26
  56. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/response_reader.rb +16 -21
  57. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/scram_authenticator.rb +3 -3
  58. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/search_result.rb +11 -1
  59. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sequence_set.rb +620 -312
  60. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/uidplus_data.rb +2 -63
  61. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap.rb +279 -162
  62. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/net-imap.gemspec +1 -1
  63. data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/rdoc.rake +1 -18
  64. data/vendor/bundle/ruby/3.4.0/gems/{net-protocol-0.2.2/LICENSE.txt → net-protocol-0.3.0/BSDL} +3 -3
  65. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.3.0/COPYING +56 -0
  66. data/vendor/bundle/ruby/3.4.0/gems/{net-protocol-0.2.2 → net-protocol-0.3.0}/lib/net/protocol.rb +58 -4
  67. data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/CHANGELOG.md +54 -1
  68. data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/utils.rb +3 -3
  69. data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/version.rb +1 -1
  70. data/vendor/bundle/ruby/3.4.0/specifications/{net-imap-0.5.15.gemspec → net-imap-0.6.6.gemspec} +4 -4
  71. data/vendor/bundle/ruby/3.4.0/specifications/{net-protocol-0.2.2.gemspec → net-protocol-0.3.0.gemspec} +5 -5
  72. data/vendor/bundle/ruby/3.4.0/specifications/{rack-3.2.6.gemspec → rack-3.2.7.gemspec} +3 -3
  73. data/views/tdiary.rconf +2 -0
  74. metadata +127 -131
  75. data/vendor/bundle/ruby/3.4.0/cache/net-imap-0.5.15.gem +0 -0
  76. data/vendor/bundle/ruby/3.4.0/cache/net-protocol-0.2.2.gem +0 -0
  77. data/vendor/bundle/ruby/3.4.0/cache/rack-3.2.6.gem +0 -0
  78. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.5.15/Rakefile +0 -13
  79. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.5.15/lib/net/imap/data_lite.rb +0 -226
  80. data/vendor/bundle/ruby/3.4.0/gems/net-imap-0.5.15/lib/net/imap/errors.rb +0 -118
  81. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/Gemfile +0 -7
  82. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/Rakefile +0 -10
  83. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/bin/console +0 -14
  84. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/bin/setup +0 -8
  85. data/vendor/bundle/ruby/3.4.0/gems/net-protocol-0.2.2/net-protocol.gemspec +0 -33
  86. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/BSDL +0 -0
  87. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/COPYING +0 -0
  88. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/LICENSE.txt +0 -0
  89. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/docs/styles.css +0 -0
  90. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/authenticators.rb +0 -0
  91. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/config/attr_type_coercion.rb +0 -0
  92. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/deprecated_client_options.rb +0 -0
  93. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/fetch_data.rb +0 -0
  94. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/flags.rb +0 -0
  95. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/anonymous_authenticator.rb +0 -0
  96. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/authentication_exchange.rb +0 -0
  97. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/authenticators.rb +0 -0
  98. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/client_adapter.rb +0 -0
  99. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/cram_md5_authenticator.rb +0 -0
  100. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/digest_md5_authenticator.rb +0 -0
  101. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/external_authenticator.rb +0 -0
  102. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/gs2_header.rb +0 -0
  103. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/login_authenticator.rb +0 -0
  104. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/oauthbearer_authenticator.rb +0 -0
  105. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/plain_authenticator.rb +0 -0
  106. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/protocol_adapters.rb +0 -0
  107. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/scram_algorithm.rb +0 -0
  108. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/stringprep.rb +0 -0
  109. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl/xoauth2_authenticator.rb +0 -0
  110. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl.rb +0 -0
  111. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/sasl_adapter.rb +0 -0
  112. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/nameprep.rb +0 -0
  113. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/saslprep.rb +0 -0
  114. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/saslprep_tables.rb +0 -0
  115. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/tables.rb +0 -0
  116. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep/trace.rb +0 -0
  117. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/stringprep.rb +0 -0
  118. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/lib/net/imap/vanished_data.rb +0 -0
  119. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/benchmarks.rake +0 -0
  120. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/rfcs.rake +0 -0
  121. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/saslprep.rake +0 -0
  122. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/rakelib/string_prep_tables_generator.rb +0 -0
  123. /data/vendor/bundle/ruby/3.4.0/gems/{net-imap-0.5.15 → net-imap-0.6.6}/sample/net-imap.rb +0 -0
  124. /data/vendor/bundle/ruby/3.4.0/gems/{net-protocol-0.2.2 → net-protocol-0.3.0}/README.md +0 -0
  125. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/CONTRIBUTING.md +0 -0
  126. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/MIT-LICENSE +0 -0
  127. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/README.md +0 -0
  128. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/SPEC.rdoc +0 -0
  129. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/auth/abstract/handler.rb +0 -0
  130. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/auth/abstract/request.rb +0 -0
  131. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/auth/basic.rb +0 -0
  132. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/bad_request.rb +0 -0
  133. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/body_proxy.rb +0 -0
  134. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/builder.rb +0 -0
  135. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/cascade.rb +0 -0
  136. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/common_logger.rb +0 -0
  137. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/conditional_get.rb +0 -0
  138. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/config.rb +0 -0
  139. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/constants.rb +0 -0
  140. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/content_length.rb +0 -0
  141. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/content_type.rb +0 -0
  142. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/deflater.rb +0 -0
  143. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/directory.rb +0 -0
  144. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/etag.rb +0 -0
  145. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/events.rb +0 -0
  146. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/files.rb +0 -0
  147. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/head.rb +0 -0
  148. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/headers.rb +0 -0
  149. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/lint.rb +0 -0
  150. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/lock.rb +0 -0
  151. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/media_type.rb +0 -0
  152. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/method_override.rb +0 -0
  153. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/mime.rb +0 -0
  154. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/mock.rb +0 -0
  155. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/mock_request.rb +0 -0
  156. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/mock_response.rb +0 -0
  157. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/multipart/generator.rb +0 -0
  158. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/multipart/parser.rb +0 -0
  159. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/multipart/uploaded_file.rb +0 -0
  160. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/multipart.rb +0 -0
  161. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/null_logger.rb +0 -0
  162. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/query_parser.rb +0 -0
  163. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/recursive.rb +0 -0
  164. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/reloader.rb +0 -0
  165. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/request.rb +0 -0
  166. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/response.rb +0 -0
  167. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/rewindable_input.rb +0 -0
  168. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/runtime.rb +0 -0
  169. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/sendfile.rb +0 -0
  170. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/show_exceptions.rb +0 -0
  171. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/show_status.rb +0 -0
  172. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/static.rb +0 -0
  173. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/tempfile_reaper.rb +0 -0
  174. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack/urlmap.rb +0 -0
  175. /data/vendor/bundle/ruby/3.4.0/gems/{rack-3.2.6 → rack-3.2.7}/lib/rack.rb +0 -0
data/lib/tdiary/view.rb CHANGED
@@ -7,12 +7,12 @@ module TDiary
7
7
  def initialize( cgi, rhtml, conf )
8
8
  super
9
9
 
10
- unless referer_filter( @cgi.referer )
11
- def @cgi.referer; nil; end
10
+ unless referer_filter( @request.referer )
11
+ @request.hide_referer!
12
12
  end
13
13
 
14
14
  # save referer to latest
15
- if (!@conf.referer_day_only or (@cgi.params['date'][0] and @cgi.params['date'][0].length == 8)) and @cgi.referer then
15
+ if (!@conf.referer_day_only or (@request.param('date') and @request.param('date').length == 8)) and @request.referer then
16
16
  ym = latest_month
17
17
  @date = ym ? Time::local( ym[0], ym[1] ) : Time::now
18
18
  @io.transaction( @date ) do |diaries|
@@ -23,7 +23,7 @@ module TDiary
23
23
  break if @diary.visible?
24
24
  end
25
25
  if @diary then
26
- @diary.add_referer( @cgi.referer )
26
+ @diary.add_referer( @request.referer )
27
27
  dirty = DIRTY_REFERER
28
28
  end
29
29
  dirty
@@ -121,7 +121,7 @@ module TDiary
121
121
 
122
122
  begin
123
123
  # time is noon for easy to calc leap second.
124
- @date = Time::local( *@cgi.params['date'][0].scan( /^(\d{4})(\d\d)(\d\d)$/ )[0] ) + 12*60*60
124
+ @date = Time::local( *@request.param('date').scan( /^(\d{4})(\d\d)(\d\d)$/ )[0] ) + 12*60*60
125
125
  load( @date )
126
126
  rescue ArgumentError, NameError
127
127
  raise TDiaryError, 'bad date'
@@ -149,8 +149,8 @@ module TDiary
149
149
  @diaries = diaries
150
150
  dirty = DIRTY_NONE
151
151
  @diary = self[date]
152
- if @diary and @cgi.referer then
153
- @diary.add_referer( @cgi.referer )
152
+ if @diary and @request.referer then
153
+ @diary.add_referer( @request.referer )
154
154
  dirty = DIRTY_REFERER
155
155
  end
156
156
  dirty
@@ -161,11 +161,11 @@ module TDiary
161
161
  end
162
162
 
163
163
  def cookie_name
164
- @cgi.cookies['tdiary'][0] or ''
164
+ @request.cgi_cookies['tdiary'][0] or ''
165
165
  end
166
166
 
167
167
  def cookie_mail
168
- @cgi.cookies['tdiary'][1] or ''
168
+ @request.cgi_cookies['tdiary'][1] or ''
169
169
  end
170
170
  end
171
171
 
@@ -189,9 +189,9 @@ module TDiary
189
189
 
190
190
  def load( date )
191
191
  @date = date
192
- @name = @cgi.params['name'][0]
193
- @mail = @cgi.params['mail'][0]
194
- @body = @cgi.params['body'][0]
192
+ @name = @request.param('name')
193
+ @mail = @request.param('mail')
194
+ @body = @request.param('body')
195
195
  @name = @conf.to_native( @name )
196
196
  @body = @conf.to_native( @body )
197
197
  @comment = Comment::new( @name, @mail, @body )
@@ -203,13 +203,18 @@ module TDiary
203
203
  if @diary and comment_filter( @diary, @comment ) then
204
204
  @diary.add_comment( @comment )
205
205
  dirty = DIRTY_COMMENT
206
- cookie_path = File::dirname( @cgi.script_name )
206
+ script_name = @request.script_name
207
+ cookie_path = script_name.empty? ? '/' : File::dirname( script_name )
207
208
  cookie_path += '/' if cookie_path !~ /\/$/
208
- @cookies << CGI::Cookie::new( {
209
- 'name' => 'tdiary',
210
- 'value' => [@name,@mail],
211
- 'path' => cookie_path,
212
- 'expires' => Time::now.gmtime + 90*24*60*60 # 90days
209
+ # the escaped 'name&mail' multi-value format must be kept;
210
+ # CGI::Cookie.parse on the reading side splits on '&'
211
+ @cookies << ::Rack::Utils.set_cookie_header( 'tdiary', {
212
+ value: [@name, @mail],
213
+ path: cookie_path,
214
+ expires: Time::now.gmtime + 90*24*60*60, # 90days
215
+ secure: @request.ssl?,
216
+ http_only: true,
217
+ same_site: :lax
213
218
  } )
214
219
  @io.clear_cache( /(latest|#{@date.strftime( '%Y%m' )})/ )
215
220
  else
@@ -254,7 +259,7 @@ module TDiary
254
259
  super
255
260
 
256
261
  begin
257
- date = Time::local( *@cgi.params['date'][0].scan( /^(\d{4})(\d\d)$/ )[0] )
262
+ date = Time::local( *@request.param('date').scan( /^(\d{4})(\d\d)$/ )[0] )
258
263
  d1 = @date.dup.gmtime if @date
259
264
  d2 = date.dup.gmtime
260
265
  if not @date or d1.year != d2.year or d1.month != d2.month then
@@ -280,7 +285,7 @@ module TDiary
280
285
  super
281
286
 
282
287
  @diaries = {}
283
- month, day = @cgi.params['date'][0].scan(/^(\d\d)(\d\d)$/)[0]
288
+ month, day = @request.param('date').scan(/^(\d\d)(\d\d)$/)[0]
284
289
  nyear(month).each do |y, m|
285
290
  @date = Time::local(y, m)
286
291
  @io.transaction(@date) do |diaries|
@@ -318,8 +323,8 @@ module TDiary
318
323
  def initialize( cgi, rhtml, conf )
319
324
  super
320
325
 
321
- if @cgi.params['date'][0] then
322
- ym = [@cgi.params['date'][0][0,4].to_i, @cgi.params['date'][0][4,2].to_i]
326
+ if @request.param('date') then
327
+ ym = [@request.param('date')[0,4].to_i, @request.param('date')[4,2].to_i]
323
328
  @date = nil
324
329
  else
325
330
  ym = latest_month
@@ -329,8 +334,8 @@ module TDiary
329
334
  @date = ym ? Time::local( ym[0], ym[1] ) : Time::now
330
335
  @io.transaction( @date ) do |diaries|
331
336
  @diaries = diaries
332
- if @cgi.params['date'][0] then
333
- @diary = @diaries[@cgi.params['date'][0][0,8]]
337
+ if @request.param('date') then
338
+ @diary = @diaries[@request.param('date')[0,8]]
334
339
  @date = @diary.date if @diary
335
340
  end
336
341
  unless @diary then
@@ -442,16 +447,16 @@ module TDiary
442
447
  end
443
448
 
444
449
  def start_date
445
- if @cgi.params['date'][0] then
446
- @cgi.params['date'][0][0,8]
450
+ if @request.param('date') then
451
+ @request.param('date')[0,8]
447
452
  else
448
453
  '99999999' # max of date string
449
454
  end
450
455
  end
451
456
 
452
457
  def limit_size( default_limit )
453
- if @cgi.params['date'][0] then
454
- date = @cgi.params['date'][0]
458
+ if @request.param('date') then
459
+ date = @request.param('date')
455
460
  limit = date[9,date.length-9].to_i
456
461
  limit = 30 if limit > 30
457
462
  limit
@@ -1,15 +1,23 @@
1
1
  module TDiary
2
2
  module ViewHelper
3
3
  def bot?
4
- @conf.bot =~ @cgi.user_agent
4
+ @conf.bot =~ view_helper_request.user_agent
5
5
  end
6
6
 
7
7
  def base_url
8
8
  if @conf.options['base_url'] && @conf.options['base_url'].length > 0
9
9
  @conf.options['base_url']
10
10
  else
11
- @cgi.base_url
11
+ view_helper_request.tdiary_base_url
12
12
  end
13
13
  end
14
+
15
+ private
16
+
17
+ # plugins include this helper into objects that hold only the @cgi
18
+ # facade (misc/plugin/makerss.rb); fall back to its wrapped request
19
+ def view_helper_request
20
+ @request || @cgi.request
21
+ end
14
22
  end
15
23
  end
data/lib/tdiary.rb CHANGED
@@ -16,6 +16,12 @@ $:.unshift File.join(File::dirname(__FILE__), '../misc/lib')
16
16
  Dir[File.join(File.dirname(__FILE__), path)].each {|dir| $:.unshift dir }
17
17
  end
18
18
 
19
+ # Set up the bundle before requiring anything that ships as a default gem.
20
+ # A CGI process starts without RUBYOPT or BUNDLE_GEMFILE (WEBrick's CGI runner
21
+ # wipes the environment), so requiring 'cgi' first activates the version bundled
22
+ # with Ruby and Bundler then fails on the version the Gemfile asks for.
23
+ require 'tdiary/environment'
24
+
19
25
  gem 'cgi' if RUBY_VERSION >= '4.0'
20
26
  require 'cgi'
21
27
  require 'uri'
@@ -23,7 +29,6 @@ require 'fileutils'
23
29
  require 'pstore'
24
30
  require 'json'
25
31
  require 'erb'
26
- require 'tdiary/environment'
27
32
  require 'tdiary/core_ext'
28
33
 
29
34
  #
data/misc/plugin/image.rb CHANGED
@@ -101,7 +101,7 @@ end
101
101
  #
102
102
  # initialize
103
103
  #
104
- @image_dir = (@options && @options['image.dir']) || File.join(TDiary.server_root, @cgi.is_a?(RackCGI) ? 'public/images' : 'images')
104
+ @image_dir = (@options && @options['image.dir']) || File.join(TDiary.server_root, @cgi.static_assets? ? 'images' : 'public/images')
105
105
  @image_dir.chop! if /\/$/ =~ @image_dir
106
106
  FileUtils.mkdir_p @image_dir unless File.exist?(@image_dir)
107
107
 
@@ -177,10 +177,10 @@ class MakeRssFull
177
177
  end
178
178
 
179
179
  def document_root
180
- if @cgi.is_a?(RackCGI)
181
- File.join(TDiary.server_root, 'public')
182
- else
180
+ if @cgi.static_assets?
183
181
  TDiary.server_root
182
+ else
183
+ File.join(TDiary.server_root, 'public')
184
184
  end
185
185
  end
186
186
  end
data/tdiary.conf.sample CHANGED
@@ -75,6 +75,14 @@
75
75
  # 必要です。blog-category プラグイン利用時は自動的に無効になります。
76
76
  #@options['plugin.cache'] = true
77
77
 
78
+ # 静的アセットの配信元URL【オプション】
79
+ # テーマやJavaScriptなどの静的ファイルを、CDNや別ホストなど任意のURLから
80
+ # 配信する場合に指定します。指定すると、Rack・CGI・FCGIのどの実行形態でも
81
+ # このURLを元にテーマやJavaScriptのURLを生成します。配信元には、Rackアプ
82
+ # リのassets配下と同じ構成(jsディレクトリとthemeディレクトリの内容をひと
83
+ # つのディレクトリにまとめた構成)でファイルを配置してください。
84
+ #@options['assets_url'] = 'https://assets.example.org/tdiary'
85
+
78
86
  # プラグインに渡すオプション【オプション】
79
87
  # プラグインによっては、tdiary.conf経由でオプションを渡すことで挙動を
80
88
  # 変更できるものがあります。@optionsはそのオプションを指定する時に使う
@@ -62,6 +62,14 @@
62
62
  # any directory for cache files by this variable.
63
63
  #@cache_path = 'path of cache files'
64
64
 
65
+ # base URL of static assets. (optional)
66
+ # Set this to serve theme and JavaScript files from another URL, such
67
+ # as a CDN. When set, every hosting mode (Rack, CGI and FCGI) builds
68
+ # theme and JavaScript URLs from it. The serving location must use the
69
+ # same merged layout as the assets/ mount of the Rack application (the
70
+ # contents of the js and theme directories under one root).
71
+ #@options['assets_url'] = 'https://assets.example.org/tdiary'
72
+
65
73
  # options for plugins. (optional)
66
74
  # Some plugins can receive options from tdiary.conf.
67
75
  # ex: a option "foo" of plugin "sample".
@@ -3,16 +3,16 @@ current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/
3
3
  creating Makefile
4
4
 
5
5
  current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/3.4.0/gems/cgi-0.5.2/ext/cgi/escape
6
- make DESTDIR\= sitearchdir\=./.gem.20260724-2392-p7gzfo sitelibdir\=./.gem.20260724-2392-p7gzfo clean
6
+ make DESTDIR\= sitearchdir\=./.gem.20260904-2409-m2rodt sitelibdir\=./.gem.20260904-2409-m2rodt clean
7
7
 
8
8
  current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/3.4.0/gems/cgi-0.5.2/ext/cgi/escape
9
- make DESTDIR\= sitearchdir\=./.gem.20260724-2392-p7gzfo sitelibdir\=./.gem.20260724-2392-p7gzfo
9
+ make DESTDIR\= sitearchdir\=./.gem.20260904-2409-m2rodt sitelibdir\=./.gem.20260904-2409-m2rodt
10
10
  compiling escape.c
11
11
  linking shared-object cgi/escape.so
12
12
 
13
13
  current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/3.4.0/gems/cgi-0.5.2/ext/cgi/escape
14
- make DESTDIR\= sitearchdir\=./.gem.20260724-2392-p7gzfo sitelibdir\=./.gem.20260724-2392-p7gzfo install
15
- /usr/bin/install -c -m 0755 escape.so ./.gem.20260724-2392-p7gzfo/cgi
14
+ make DESTDIR\= sitearchdir\=./.gem.20260904-2409-m2rodt sitelibdir\=./.gem.20260904-2409-m2rodt install
15
+ /usr/bin/install -c -m 0755 escape.so ./.gem.20260904-2409-m2rodt/cgi
16
16
 
17
17
  current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/3.4.0/gems/cgi-0.5.2/ext/cgi/escape
18
- make DESTDIR\= sitearchdir\=./.gem.20260724-2392-p7gzfo sitelibdir\=./.gem.20260724-2392-p7gzfo clean
18
+ make DESTDIR\= sitearchdir\=./.gem.20260904-2409-m2rodt sitelibdir\=./.gem.20260904-2409-m2rodt clean
@@ -6,10 +6,10 @@ checking for altzone in time.h with -Werror... no
6
6
  creating Makefile
7
7
 
8
8
  current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/3.4.0/gems/date-3.5.1/ext/date
9
- make DESTDIR\= sitearchdir\=./.gem.20260724-2392-lclah2 sitelibdir\=./.gem.20260724-2392-lclah2 clean
9
+ make DESTDIR\= sitearchdir\=./.gem.20260904-2409-mbib62 sitelibdir\=./.gem.20260904-2409-mbib62 clean
10
10
 
11
11
  current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/3.4.0/gems/date-3.5.1/ext/date
12
- make DESTDIR\= sitearchdir\=./.gem.20260724-2392-lclah2 sitelibdir\=./.gem.20260724-2392-lclah2
12
+ make DESTDIR\= sitearchdir\=./.gem.20260904-2409-mbib62 sitelibdir\=./.gem.20260904-2409-mbib62
13
13
  compiling date_core.c
14
14
  compiling date_parse.c
15
15
  compiling date_strftime.c
@@ -17,8 +17,8 @@ compiling date_strptime.c
17
17
  linking shared-object date_core.so
18
18
 
19
19
  current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/3.4.0/gems/date-3.5.1/ext/date
20
- make DESTDIR\= sitearchdir\=./.gem.20260724-2392-lclah2 sitelibdir\=./.gem.20260724-2392-lclah2 install
21
- /usr/bin/install -c -m 0755 date_core.so ./.gem.20260724-2392-lclah2
20
+ make DESTDIR\= sitearchdir\=./.gem.20260904-2409-mbib62 sitelibdir\=./.gem.20260904-2409-mbib62 install
21
+ /usr/bin/install -c -m 0755 date_core.so ./.gem.20260904-2409-mbib62
22
22
 
23
23
  current directory: /home/runner/work/tdiary-core/tdiary-core/vendor/bundle/ruby/3.4.0/gems/date-3.5.1/ext/date
24
- make DESTDIR\= sitearchdir\=./.gem.20260724-2392-lclah2 sitelibdir\=./.gem.20260724-2392-lclah2 clean
24
+ make DESTDIR\= sitearchdir\=./.gem.20260904-2409-mbib62 sitelibdir\=./.gem.20260904-2409-mbib62 clean
@@ -7,10 +7,11 @@ gemspec
7
7
  # gem "digest" # not included as a workaround for #576
8
8
  gem "strscan"
9
9
  gem "base64"
10
+ gem "psych", ">= 5.3.0" # 5.2.5 for Data serialization, 5.3.0 for TruffleRuby
10
11
 
11
12
  gem "irb"
12
13
  gem "rake"
13
- gem "rdoc"
14
+ gem "rdoc", ">= 7.2.0"
14
15
  gem "test-unit"
15
16
  gem "test-unit-ruby-core", git: "https://github.com/ruby/test-unit-ruby-core"
16
17
 
@@ -19,7 +20,5 @@ gem "benchmark-driver", require: false
19
20
  gem "vernier", require: false, platform: :mri
20
21
 
21
22
  group :test do
22
- gem "simplecov", require: false, platforms: %i[mri windows]
23
- gem "simplecov-html", require: false, platforms: %i[mri windows]
24
- gem "simplecov-json", require: false, platforms: %i[mri windows]
23
+ gem "simplecov", ">= 1.0.0", require: false, platforms: %i[mri windows]
25
24
  end
@@ -61,9 +61,9 @@ imap.search(["BEFORE", "30-Apr-2003", "SINCE", "1-Apr-2003"]).each do |message_i
61
61
  else
62
62
  imap.copy(message_id, "Mail/sent-apr03")
63
63
  imap.store(message_id, "+FLAGS", [:Deleted])
64
+ imap.expunge
64
65
  end
65
66
  end
66
- imap.expunge
67
67
  ```
68
68
 
69
69
  ## Development
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+ require "rake/clean"
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << "test/lib"
9
+ t.ruby_opts << "-rhelper"
10
+ t.test_files = FileList["test/**/test_*.rb"]
11
+ end
12
+
13
+ task :default => :test
14
+
15
+ desc "Output coverage data report, and error when threshholds aren't met"
16
+ task "coverage:report" do
17
+ require "simplecov"
18
+ SimpleCov.collate "coverage/.resultset.json" do
19
+ coverage(:line) do
20
+ minimum 90
21
+ minimum_per_file 40
22
+ end
23
+ end
24
+ end
@@ -3,7 +3,6 @@
3
3
  require "date"
4
4
 
5
5
  require_relative "errors"
6
- require_relative "data_lite"
7
6
 
8
7
  # :enddoc:
9
8
 
@@ -16,6 +15,9 @@ module Net
16
15
  case data
17
16
  when nil
18
17
  when String
18
+ if data.include?("\0")
19
+ raise DataFormatError, "String argument contains NULL byte"
20
+ end
19
21
  when Integer
20
22
  # Covers modseq-valzer, which is the largest valid IMAP integer
21
23
  if data.negative?
@@ -56,33 +58,42 @@ module Net
56
58
  end
57
59
  end
58
60
 
61
+ UNQUOTABLE_CHARS = /[\0\r\n]/
62
+ ASTRING_SPECIALS = /[(){ \x00-\x1f\x7f%*"\\]/
63
+ private_constant :UNQUOTABLE_CHARS, :ASTRING_SPECIALS
64
+
65
+ # Sends generic strings formatted as +astring+:
66
+ # * as an atom (note: this is based on +ASTRING-CHAR+, not +ATOM-CHAR+)
67
+ # * as a quoted string
68
+ # * as a literal (may send non-synchronizing)
69
+ #
70
+ # NOTE: This does not validate that +str+ contains no +NULL+ bytes.
59
71
  def send_string_data(str, tag = nil)
60
72
  if str.empty?
73
+ # same as send_quoted_string(str), but incompatible encoding is allowed
61
74
  put_string('""')
62
- elsif str.match?(/[\r\n]/n)
63
- # literal, because multiline
64
- send_literal(str, tag)
65
- elsif !str.ascii_only?
66
- if @utf8_strings
67
- # quoted string
68
- send_quoted_string(str)
69
- else
70
- # literal, because of non-ASCII bytes
71
- send_literal(str, tag)
72
- end
73
- elsif str.match?(/[(){ \x00-\x1f\x7f%*"\\]/n)
74
- # quoted string
75
+ elsif str.ascii_only? && !str.match?(ASTRING_SPECIALS)
76
+ # valid +astring+ atom: non-empty, ASCII only, no ASTRING_SPECIALS
77
+ put_string(str)
78
+ elsif text_encodable?(str) && !str.match?(UNQUOTABLE_CHARS)
75
79
  send_quoted_string(str)
76
80
  else
77
- put_string(str)
81
+ send_literal(str, tag)
78
82
  end
79
83
  end
80
84
 
81
- def send_quoted_string(str)
82
- put_string('"' + str.gsub(/["\\]/, "\\\\\\&") + '"')
85
+ # Encodable as +text+ (which is a superset of +quoted+):
86
+ # * ASCII only (for any ASCII compatible encoding)
87
+ # * or valid UTF-8 (when the connection supports it)
88
+ def text_encodable?(str)
89
+ str.ascii_only? || (utf8_enabled? &&
90
+ str.encoding == Encoding::UTF_8 &&
91
+ str.valid_encoding?)
83
92
  end
84
93
 
85
- def send_binary_literal(*a, **kw); send_literal(*a, **kw, binary: true) end
94
+ def send_quoted_string(str) = QuotedString.new(data: str).send_data(self)
95
+
96
+ def send_binary_literal(*, **) = send_literal(*, **, binary: true)
86
97
 
87
98
  # `non_sync` is an optional tri-state flag:
88
99
  # * `true` -> Force non-synchronizing `LITERAL+`/`LITERAL-` behavior.
@@ -90,7 +101,6 @@ module Net
90
101
  # non-synchronizing literal, or literal is too large for LITERAL-.
91
102
  # * `false` -> Force normal synchronizing literal behavior.
92
103
  # * `nil` -> (default) Currently behaves like `false` (will be dynamic).
93
- # TODO: Dynamic, based on capabilities and bytesize.
94
104
  def send_literal(str, tag = nil, binary: false, non_sync: nil)
95
105
  bytesize = str.bytesize
96
106
  synchronize do
@@ -100,6 +110,7 @@ module Net
100
110
  raise DataFormatError, "Connection closed: " \
101
111
  "Cannot send non-synchronizing literal without known server support"
102
112
  end
113
+ non_sync = non_sync_literal?(bytesize) if non_sync.nil?
103
114
  prefix = "~" if binary
104
115
  plus = "+" if non_sync
105
116
  put_string("#{prefix}{#{bytesize}#{plus}}\r\n")
@@ -111,8 +122,7 @@ module Net
111
122
  @continuation_request_exception = nil
112
123
  begin
113
124
  @continuation_request_arrival.wait
114
- e = @continuation_request_exception || @exception
115
- raise e if e
125
+ reraise @continuation_request_exception || @exception
116
126
  put_string(str)
117
127
  ensure
118
128
  @continued_command_tag = nil
@@ -121,6 +131,11 @@ module Net
121
131
  end
122
132
  end
123
133
 
134
+ def non_sync_literal?(bytesize)
135
+ bytesize <= config.max_non_synchronizing_literal \
136
+ && non_sync_literal_allowed?(bytesize)
137
+ end
138
+
124
139
  def non_sync_literal_allowed?(bytesize)
125
140
  return unless capabilities_cached?
126
141
  return "+" if capable?("LITERAL+")
@@ -152,6 +167,9 @@ module Net
152
167
  def send_date_data(date) put_string Net::IMAP.encode_date(date) end
153
168
  def send_time_data(time) put_string Net::IMAP.encode_time(time) end
154
169
 
170
+ # NOTE: Currently for internal use only. The API is expected to change.
171
+ Command = Data.define(:tag, :name) # :nodoc:
172
+
155
173
  CommandData = Data.define(:data) do # :nodoc:
156
174
  def self.validate(...)
157
175
  data = new(...)
@@ -249,10 +267,10 @@ module Net
249
267
  parts = []
250
268
  while data.match(/(~)?\{(0|[1-9]\d*)(\+)?\}\r\n/n)
251
269
  text, binary, bytesize, non_sync, data = $`, !!$1, $2, !!$3, $'
252
- bytesize = Integer bytesize, 10
270
+ bytesize = NumValidator.coerce_number64 bytesize
253
271
  parts << RawText[text] unless text.empty?
254
272
  parts << extract_literal(data, binary:, bytesize:, non_sync:)
255
- data[0, bytesize] = ""
273
+ data.bytesplice(0, bytesize, "")
256
274
  end
257
275
  parts << RawText[data] unless data.empty?
258
276
  parts
@@ -269,6 +287,17 @@ module Net
269
287
  private_class_method :extract_literal
270
288
  end
271
289
 
290
+ # Please note that +ATOM-CHAR+ and +atom+ are not the same as +ASTRING-char+
291
+ # and the atom form of +astring+. +astring+ allows <tt>]</tt>, but +atom+
292
+ # does not.
293
+ #
294
+ # Generic string arguments in Net::IMAP use +astring+, so they will send as
295
+ # atoms even if they contain <tt>]</tt>.
296
+ #
297
+ # This class is used by:
298
+ # * to validate generic symbol arguments, as the superclass of Flag
299
+ # * to validate #enable +capabilities+
300
+ # * to validate #store (and #uid_store) +attr+
272
301
  class Atom < CommandData # :nodoc:
273
302
  def initialize(**)
274
303
  super
@@ -318,7 +347,7 @@ module Net
318
347
  validate
319
348
  end
320
349
 
321
- def bytesize; data.bytesize end
350
+ def bytesize = data.bytesize
322
351
 
323
352
  def validate
324
353
  if data.include?("\0")
@@ -333,7 +362,7 @@ module Net
333
362
  end
334
363
 
335
364
  class Literal8 < Literal # :nodoc:
336
- def validate; nil end # all bytes are okay
365
+ def validate = nil # all bytes are okay
337
366
 
338
367
  def send_data(imap, tag)
339
368
  imap.__send__(:send_binary_literal, data, tag, non_sync:)
@@ -372,73 +401,6 @@ module Net
372
401
  end
373
402
  end
374
403
 
375
- # *DEPRECATED*. Replaced by SequenceSet.
376
- class MessageSet < CommandData # :nodoc:
377
- def send_data(imap, tag)
378
- imap.__send__(:put_string, format_internal(data))
379
- end
380
-
381
- def validate
382
- validate_internal(data)
383
- end
384
-
385
- private
386
-
387
- def initialize(data:)
388
- super
389
- warn("DEPRECATED: #{MessageSet} should be replaced with #{SequenceSet}.",
390
- uplevel: 1, category: :deprecated)
391
- begin
392
- # to ensure the input works with SequenceSet, too
393
- SequenceSet.new(data)
394
- rescue
395
- warn "MessageSet input is incompatible with SequenceSet: [%s] %s" % [
396
- $!.class, $!.message
397
- ]
398
- end
399
- end
400
-
401
- def format_internal(data)
402
- case data
403
- when "*"
404
- return data
405
- when Integer
406
- if data == -1
407
- return "*"
408
- else
409
- return data.to_s
410
- end
411
- when Range
412
- return format_internal(data.first) +
413
- ":" + format_internal(data.last)
414
- when Array
415
- return data.collect {|i| format_internal(i)}.join(",")
416
- when ThreadMember
417
- return data.seqno.to_s +
418
- ":" + data.children.collect {|i| format_internal(i).join(",")}
419
- end
420
- end
421
-
422
- def validate_internal(data)
423
- case data
424
- when "*"
425
- when Integer
426
- NumValidator.ensure_nz_number(data)
427
- when Range
428
- when Array
429
- data.each do |i|
430
- validate_internal(i)
431
- end
432
- when ThreadMember
433
- data.children.each do |i|
434
- validate_internal(i)
435
- end
436
- else
437
- raise DataFormatError, data.inspect
438
- end
439
- end
440
- end
441
-
442
404
  class ClientID < CommandData # :nodoc:
443
405
 
444
406
  def send_data(imap, tag)
@@ -476,6 +438,14 @@ module Net
476
438
 
477
439
  module_function
478
440
 
441
+ def literal_or_literal8(input, name: "argument")
442
+ return input if input in Literal | Literal8
443
+ data = String.try_convert(input) \
444
+ or raise TypeError, "expected #{name} to be String, got #{input.class}"
445
+ type = data.include?("\0") ? Literal8 : Literal
446
+ type.new(data:)
447
+ end
448
+
479
449
  # Allows symbols in addition to strings
480
450
  def valid_string?(str)
481
451
  str.is_a?(Symbol) || str.respond_to?(:to_str)
@@ -27,24 +27,23 @@ module Net
27
27
 
28
28
  def self.attr_accessor(name) # :nodoc: internal API
29
29
  name = name.to_sym
30
+ raise ArgumentError, "already defined #{name}" if attributes.include?(name)
31
+ attributes << name
30
32
  def_delegators :data, name, :"#{name}="
31
33
  end
32
34
 
33
- def self.attributes
34
- instance_methods.grep(/=\z/).map { _1.to_s.delete_suffix("=").to_sym }
35
- end
36
- private_class_method :attributes
35
+ # An array of Config attribute names
36
+ singleton_class.attr_reader :attributes
37
+ @attributes = []
37
38
 
38
39
  def self.struct # :nodoc: internal API
39
- unless defined?(self::Struct)
40
- const_set :Struct, Struct.new(*attributes)
41
- end
42
- self::Struct
40
+ attributes.freeze
41
+ Struct.new(*attributes)
43
42
  end
44
43
 
45
44
  def initialize # :notnew:
46
45
  super()
47
- @data = AttrAccessors.struct.new
46
+ @data = Config::Struct.new
48
47
  end
49
48
 
50
49
  # Freezes the internal attributes struct, in addition to +self+.