bson 4.15.0 → 5.0.2

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 (153) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +94 -10
  3. data/Rakefile +68 -39
  4. data/ext/bson/bson-native.h +12 -4
  5. data/ext/bson/extconf.rb +8 -3
  6. data/ext/bson/init.c +11 -11
  7. data/ext/bson/read.c +39 -9
  8. data/ext/bson/util.c +171 -16
  9. data/ext/bson/write.c +34 -39
  10. data/lib/bson/active_support.rb +1 -0
  11. data/lib/bson/array.rb +58 -32
  12. data/lib/bson/big_decimal.rb +16 -6
  13. data/lib/bson/binary.rb +271 -129
  14. data/lib/bson/boolean.rb +1 -0
  15. data/lib/bson/code.rb +10 -12
  16. data/lib/bson/code_with_scope.rb +9 -11
  17. data/lib/bson/config.rb +1 -27
  18. data/lib/bson/date.rb +2 -1
  19. data/lib/bson/date_time.rb +2 -1
  20. data/lib/bson/db_pointer.rb +12 -13
  21. data/lib/bson/dbref.rb +11 -9
  22. data/lib/bson/decimal128/builder.rb +10 -9
  23. data/lib/bson/decimal128.rb +25 -111
  24. data/lib/bson/document.rb +1 -0
  25. data/lib/bson/environment.rb +1 -0
  26. data/lib/bson/error/bson_decode_error.rb +11 -0
  27. data/lib/bson/error/ext_json_parse_error.rb +11 -0
  28. data/lib/bson/error/illegal_key.rb +23 -0
  29. data/lib/bson/error/invalid_binary_type.rb +37 -0
  30. data/lib/bson/error/invalid_dbref_argument.rb +12 -0
  31. data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
  32. data/lib/bson/error/invalid_decimal128_range.rb +27 -0
  33. data/lib/bson/error/invalid_decimal128_string.rb +26 -0
  34. data/lib/bson/error/invalid_key.rb +24 -0
  35. data/lib/bson/error/invalid_object_id.rb +11 -0
  36. data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
  37. data/lib/bson/error/unrepresentable_precision.rb +19 -0
  38. data/lib/bson/error/unserializable_class.rb +13 -0
  39. data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
  40. data/lib/bson/error/unsupported_type.rb +11 -0
  41. data/lib/bson/error.rb +16 -28
  42. data/lib/bson/ext_json.rb +2 -1
  43. data/lib/bson/false_class.rb +2 -1
  44. data/lib/bson/float.rb +3 -2
  45. data/lib/bson/hash.rb +128 -73
  46. data/lib/bson/int32.rb +17 -5
  47. data/lib/bson/int64.rb +17 -5
  48. data/lib/bson/integer.rb +4 -5
  49. data/lib/bson/json.rb +1 -0
  50. data/lib/bson/max_key.rb +8 -10
  51. data/lib/bson/min_key.rb +8 -10
  52. data/lib/bson/nil_class.rb +1 -0
  53. data/lib/bson/object.rb +7 -27
  54. data/lib/bson/object_id.rb +84 -120
  55. data/lib/bson/open_struct.rb +3 -2
  56. data/lib/bson/regexp.rb +36 -65
  57. data/lib/bson/registry.rb +2 -6
  58. data/lib/bson/specialized.rb +2 -1
  59. data/lib/bson/string.rb +4 -27
  60. data/lib/bson/symbol.rb +23 -20
  61. data/lib/bson/time.rb +3 -2
  62. data/lib/bson/time_with_zone.rb +13 -1
  63. data/lib/bson/timestamp.rb +3 -2
  64. data/lib/bson/true_class.rb +2 -1
  65. data/lib/bson/undefined.rb +15 -1
  66. data/lib/bson/version.rb +3 -1
  67. data/lib/bson.rb +3 -2
  68. data/spec/bson/array_spec.rb +19 -60
  69. data/spec/bson/big_decimal_spec.rb +16 -4
  70. data/spec/bson/binary_spec.rb +129 -81
  71. data/spec/bson/binary_uuid_spec.rb +1 -0
  72. data/spec/bson/boolean_spec.rb +1 -0
  73. data/spec/bson/byte_buffer_read_spec.rb +1 -0
  74. data/spec/bson/byte_buffer_spec.rb +1 -0
  75. data/spec/bson/byte_buffer_write_spec.rb +1 -0
  76. data/spec/bson/code_spec.rb +5 -3
  77. data/spec/bson/code_with_scope_spec.rb +5 -3
  78. data/spec/bson/config_spec.rb +1 -35
  79. data/spec/bson/date_spec.rb +1 -0
  80. data/spec/bson/date_time_spec.rb +1 -0
  81. data/spec/bson/dbref_legacy_spec.rb +20 -3
  82. data/spec/bson/dbref_spec.rb +9 -9
  83. data/spec/bson/decimal128_spec.rb +40 -20
  84. data/spec/bson/document_as_spec.rb +1 -0
  85. data/spec/bson/document_spec.rb +1 -1
  86. data/spec/bson/ext_json_parse_spec.rb +1 -0
  87. data/spec/bson/false_class_spec.rb +8 -0
  88. data/spec/bson/float_spec.rb +8 -3
  89. data/spec/bson/hash_as_spec.rb +1 -0
  90. data/spec/bson/hash_spec.rb +87 -75
  91. data/spec/bson/int32_spec.rb +21 -6
  92. data/spec/bson/int64_spec.rb +21 -6
  93. data/spec/bson/integer_spec.rb +45 -13
  94. data/spec/bson/json_spec.rb +1 -0
  95. data/spec/bson/max_key_spec.rb +5 -3
  96. data/spec/bson/min_key_spec.rb +5 -3
  97. data/spec/bson/nil_class_spec.rb +1 -0
  98. data/spec/bson/object_id_spec.rb +57 -4
  99. data/spec/bson/object_spec.rb +2 -1
  100. data/spec/bson/open_struct_spec.rb +14 -71
  101. data/spec/bson/raw_spec.rb +9 -15
  102. data/spec/bson/regexp_spec.rb +4 -3
  103. data/spec/bson/registry_spec.rb +2 -1
  104. data/spec/bson/string_spec.rb +13 -38
  105. data/spec/bson/symbol_raw_spec.rb +25 -0
  106. data/spec/bson/symbol_spec.rb +15 -18
  107. data/spec/bson/time_spec.rb +1 -0
  108. data/spec/bson/time_with_zone_spec.rb +1 -0
  109. data/spec/bson/timestamp_spec.rb +1 -0
  110. data/spec/bson/true_class_spec.rb +8 -0
  111. data/spec/bson/undefined_spec.rb +27 -0
  112. data/spec/bson_spec.rb +1 -0
  113. data/spec/runners/common_driver.rb +6 -5
  114. data/spec/runners/corpus.rb +6 -0
  115. data/spec/runners/corpus_legacy.rb +1 -0
  116. data/spec/spec_helper.rb +1 -0
  117. data/spec/spec_tests/common_driver_spec.rb +9 -4
  118. data/spec/spec_tests/corpus_legacy_spec.rb +1 -0
  119. data/spec/spec_tests/corpus_spec.rb +13 -3
  120. data/spec/spec_tests/data/corpus/binary.json +5 -0
  121. data/spec/spec_tests/data/corpus/code.json +13 -13
  122. data/spec/spec_tests/data/corpus/decimal128-4.json +48 -0
  123. data/spec/spec_tests/data/corpus/decimal128-6.json +12 -0
  124. data/spec/spec_tests/data/corpus/decimal128-7.json +4 -0
  125. data/spec/spec_tests/data/corpus/document.json +20 -0
  126. data/spec/spec_tests/data/corpus/symbol.json +7 -7
  127. data/spec/spec_tests/data/corpus/top.json +18 -3
  128. data/spec/support/shared_examples.rb +28 -5
  129. data/spec/support/spec_config.rb +1 -0
  130. data/spec/support/utils.rb +49 -1
  131. metadata +114 -164
  132. checksums.yaml.gz.sig +0 -0
  133. data/spec/shared/LICENSE +0 -20
  134. data/spec/shared/bin/get-mongodb-download-url +0 -17
  135. data/spec/shared/bin/s3-copy +0 -45
  136. data/spec/shared/bin/s3-upload +0 -69
  137. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  138. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  139. data/spec/shared/lib/mrss/constraints.rb +0 -386
  140. data/spec/shared/lib/mrss/docker_runner.rb +0 -271
  141. data/spec/shared/lib/mrss/event_subscriber.rb +0 -200
  142. data/spec/shared/lib/mrss/lite_constraints.rb +0 -191
  143. data/spec/shared/lib/mrss/server_version_registry.rb +0 -120
  144. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  145. data/spec/shared/lib/mrss/utils.rb +0 -15
  146. data/spec/shared/share/Dockerfile.erb +0 -338
  147. data/spec/shared/share/haproxy-1.conf +0 -16
  148. data/spec/shared/share/haproxy-2.conf +0 -17
  149. data/spec/shared/shlib/distro.sh +0 -74
  150. data/spec/shared/shlib/server.sh +0 -367
  151. data/spec/shared/shlib/set_env.sh +0 -131
  152. data.tar.gz.sig +0 -0
  153. metadata.gz.sig +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d0c420e8204cb354acfc6adadb5097b71f4a8346620a5461153c6461aece1e2
4
- data.tar.gz: ce5e7172180e7e9f5c60d2af3207b50e0ead96283d36828e75a118cc53cdd7fa
3
+ metadata.gz: 41a002d14b035c9cf01534ee489ca61c012202aac1e2729fa850960c359ba5cd
4
+ data.tar.gz: f63478ad673c6dfbed91eaed8477b45287a264fa6c06e29d2273c41a0951e4e1
5
5
  SHA512:
6
- metadata.gz: 990f1be935132660ad51dab98c9233e12f9af5d03eac5f52a5bef82a78af2d258c12721564bfaf042977766c65d9adc7dbc7d88241283207213fe9ac15c9a024
7
- data.tar.gz: 8004b3cd0e51a769df76fd9027058f403efe6b5a565eff39aca3e43f700f0b77a7a670793dfb043d0cf963537eda0426e8a885dd4044adc2800934beaeb59286
6
+ metadata.gz: 67721ba06f0154a5dc37bc460602f878843243706e0194375c0350a095774beb06ba7a5b861b137d95bd0e753ed74b35d3b541283864aaec02b61dd94952d9ed
7
+ data.tar.gz: 525cc2a1da23ceaec40243cf7cc9ab504e81c11b56bf22e9f51f156c24294231fcd300874ae3b22c80fa473be568d84d43c627eabd4434c3895458c332364f6a
data/README.md CHANGED
@@ -1,34 +1,122 @@
1
1
  BSON
2
2
  [![Gem Version][rubygems-img]][rubygems-url]
3
3
  [![Build Status][ghactions-img]][ghactions-url]
4
- [![Coverage Status][coveralls-img]][coveralls-url]
5
- [![Inline docs][inch-img]][inch-url]
6
4
  ====
7
5
 
8
6
  An implementation of the BSON specification in Ruby.
9
7
 
8
+ Installation
9
+ ------------
10
+
11
+ BSON can be installed via RubyGems:
12
+
13
+ ```
14
+ > gem install bson
15
+ ```
16
+
17
+ Or by adding it to your project's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'bson'
21
+ ```
22
+
23
+ ### Release Integrity
24
+
25
+ Each release of the BSON library for Ruby after version 5.0.0 has been automatically built and signed using the team's GPG key.
26
+
27
+ To verify the bson gem file:
28
+
29
+ 1. [Download the GPG key](https://pgp.mongodb.com/ruby-driver.asc).
30
+ 2. Import the key into your GPG keyring with `gpg --import ruby-driver.asc`.
31
+ 3. Download the gem file (if you don't already have it). You can download it from RubyGems with `gem fetch bson`, or you can download it from the [releases page](https://github.com/mongodb/bson-ruby/releases) on GitHub.
32
+ 4. Download the corresponding detached signature file from the [same release](https://github.com/mongodb/bson-ruby/releases). Look at the bottom of the release that corresponds to the gem file, under the 'Assets' list, for a `.sig` file with the same version number as the gem you wish to install.
33
+ 5. Verify the gem with `gpg --verify bson-X.Y.Z.gem.sig bson-X.Y.Z.gem` (replacing `X.Y.Z` with the actual version number).
34
+
35
+ You are looking for text like "Good signature from "MongoDB Ruby Driver Release Signing Key <packaging@mongodb.com>" in the output. If you see that, the signature was found to correspond to the given gem file.
36
+
37
+ (Note that other output, like "This key is not certified with a trusted signature!", is related to *web of trust* and depends on how strongly you, personally, trust the `ruby-driver.asc` key that you downloaded from us. To learn more, see https://www.gnupg.org/gph/en/manual/x334.html)
38
+
39
+ ### Why not use RubyGems' gem-signing functionality?
40
+
41
+ RubyGems' own gem signing is problematic, most significantly because there is no established chain of trust related to the keys used to sign gems. RubyGems' own documentation admits that "this method of signing gems is not widely used" (see https://guides.rubygems.org/security/). Discussions about this in the RubyGems community have been off-and-on for more than a decade, and while a solution will eventually arrive, we have settled on using GPG instead for the following reasons:
42
+
43
+ 1. Many of the other driver teams at MongoDB are using GPG to sign their product releases. Consistency with the other teams means that we can reuse existing tooling for our own product releases.
44
+ 2. GPG is widely available and has existing tools and procedures for dealing with web of trust (though they are admittedly quite arcane and intimidating to the uninitiated, unfortunately).
45
+
46
+ Ultimately, most users do not bother to verify gems, and will not be impacted by our choice of GPG over RubyGems' native method.
47
+
10
48
  Compatibility
11
49
  -------------
12
50
 
13
- BSON is tested against MRI (2.5) and JRuby (9.2+).
51
+ BSON is tested against MRI (2.7+) and JRuby (9.3+).
14
52
 
15
53
  Documentation
16
54
  -------------
17
55
 
18
56
  Current documentation can be found
19
- [here](http://docs.mongodb.org/ecosystem/tutorial/ruby-bson-tutorial/#ruby-bson-tutorial).
57
+ [here](https://www.mongodb.com/docs/ruby-driver/current/bson-tutorials/).
20
58
 
21
59
  API Documentation
22
60
  -----------------
23
61
 
24
- The [API Documentation](https://api.mongodb.com/bson-ruby/current/) is
25
- located at api.mongodb.com.
62
+ The [API Documentation](https://www.mongodb.com/docs/ruby-driver/master/api/) is
63
+ located at mongodb.com/docs.
26
64
 
27
65
  BSON Specification
28
66
  ------------------
29
67
 
30
68
  The [BSON specification](http://bsonspec.org) is at bsonspec.org.
31
69
 
70
+ ## Bugs & Feature Requests
71
+
72
+ To report a bug in the `bson` gem or request a feature:
73
+
74
+ 1. Visit [our issue tracker](https://jira.mongodb.org/) and login
75
+ (or create an account if you do not have one already).
76
+ 2. Navigate to the [RUBY project](https://jira.mongodb.org/browse/RUBY).
77
+ 3. Click 'Create Issue' and fill out all of the applicable form fields, making
78
+ sure to select `BSON` in the _Component/s_ field.
79
+
80
+ When creating an issue, please keep in mind that all information in JIRA
81
+ for the RUBY project, as well as the core server (the SERVER project),
82
+ is publicly visible.
83
+
84
+ **PLEASE DO:**
85
+
86
+ - Provide as much information as possible about the issue.
87
+ - Provide detailed steps for reproducing the issue.
88
+ - Provide any applicable code snippets, stack traces and log data.
89
+ - Specify version numbers of the `bson` gem and/or Ruby driver and MongoDB
90
+ server.
91
+
92
+ **PLEASE DO NOT:**
93
+
94
+ - Provide any sensitive data or server logs.
95
+ - Report potential security issues publicly (see 'Security Issues' below).
96
+
97
+ ## Security Issues
98
+
99
+ If you have identified a potential security-related issue in the `bson` gem
100
+ (or any other MongoDB product), please report it by following the
101
+ [instructions here](https://www.mongodb.com/docs/manual/tutorial/create-a-vulnerability-report).
102
+
103
+ ## Product Feature Requests
104
+
105
+ To request a feature which is not specific to the `bson` gem, or which
106
+ affects more than the `bson` gem and/or Ruby driver alone (for example, a
107
+ feature which requires MongoDB server support), please submit your idea through
108
+ the [MongoDB Feedback Forum](https://feedback.mongodb.com/forums/924286-drivers).
109
+
110
+ ## Maintenance and Bug Fix Policy
111
+
112
+ New library functionality is generally added in a backwards-compatible manner
113
+ and results in new minor releases. Bug fixes are generally made on
114
+ master first and are backported to the current minor library release. Exceptions
115
+ may be made on a case-by-case basis, for example security fixes may be
116
+ backported to older stable branches. Only the most recent minor release
117
+ is officially supported. Customers should use the most recent release in
118
+ their applications.
119
+
32
120
  Versioning
33
121
  ----------
34
122
 
@@ -56,7 +144,3 @@ limitations under the License.
56
144
  [rubygems-url]: http://badge.fury.io/rb/bson
57
145
  [ghactions-img]: https://github.com/mongodb/bson-ruby/actions/workflows/bson-ruby.yml/badge.svg?query=branch%3Amaster
58
146
  [ghactions-url]: https://github.com/mongodb/bson-ruby/actions/workflows/bson-ruby.yml?query=branch%3Amaster
59
- [coveralls-img]: https://coveralls.io/repos/mongodb/bson-ruby/badge.svg?branch=master
60
- [coveralls-url]: https://coveralls.io/r/mongodb/bson-ruby?branch=master
61
- [inch-img]: http://inch-ci.org/github/mongodb/bson-ruby.svg?branch=master
62
- [inch-url]: http://inch-ci.org/github/mongodb/bson-ruby
data/Rakefile CHANGED
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:todo all
3
+
1
4
  # Copyright (C) 2009-2013 MongoDB Inc.
2
5
  #
3
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -32,6 +35,8 @@ if jruby?
32
35
  ext.name = "bson-ruby"
33
36
  ext.ext_dir = "src"
34
37
  ext.lib_dir = "lib"
38
+ ext.target_version = ENV['TARGET_VERSION'] if ENV['TARGET_VERSION']
39
+ ext.source_version = ENV['SOURCE_VERSION'] if ENV['SOURCE_VERSION']
35
40
  end
36
41
  else
37
42
  require "rake/extensiontask"
@@ -42,28 +47,37 @@ else
42
47
  end
43
48
  end
44
49
 
45
- require "bson/version"
50
+ RSpec::Core::RakeTask.new(:rspec)
46
51
 
47
- def extension
48
- RUBY_PLATFORM =~ /darwin/ ? "bundle" : "so"
52
+ desc 'Build the bson gem'
53
+ task :build => [ :clean_all, *(jruby? ? :compile : nil) ] do
54
+ output = "--output=#{ENV['GEM_FILE_NAME']}" if ENV['GEM_FILE_NAME']
55
+ system "gem build #{output} bson.gemspec"
49
56
  end
50
57
 
51
- require_relative "perf/bench"
52
-
53
- RSpec::Core::RakeTask.new(:rspec)
58
+ # `rake version` is used by the deployment system so get the release version
59
+ # of the product beng deployed. It must do nothing more than just print the
60
+ # product version number.
61
+ desc 'Print the current version of the Ruby-BSON library'
62
+ task :version do
63
+ require 'bson/version'
64
+ puts BSON::VERSION
65
+ end
54
66
 
55
- if jruby?
56
- task :build => [ :clean_all, :compile ] do
57
- system "gem build bson.gemspec"
58
- end
59
- else
60
- task :build => :clean_all do
61
- system "gem build bson.gemspec"
62
- end
67
+ # `rake gem_file_name` is used by the deployment system so get the name of
68
+ # the gem file to be generated. It must do nothing more than just print the
69
+ # name of the gem file to generate.
70
+ desc 'Print the name of the gem file to generate.'
71
+ task :gem_file_name do
72
+ require 'bson/version'
73
+ base = "bson-#{BSON::VERSION}"
74
+ base << '-java' if jruby?
75
+ puts "#{base}.gem"
63
76
  end
64
77
 
65
78
  task :clean_all => :clean do
66
- FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson_native.#{extension}"))
79
+ FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson_native.bundle"))
80
+ FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson_native.so"))
67
81
  FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson_native.o"))
68
82
  FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson-ruby.jar"))
69
83
  end
@@ -72,49 +86,63 @@ task :spec => :compile do
72
86
  Rake::Task["rspec"].invoke
73
87
  end
74
88
 
75
- # Run bundle exec rake release with mri and jruby. Ex:
76
- #
77
- # rvm use 2.1.0@bson
78
- # bundle exec rake release
79
- # rvm use jruby@bson
80
- # bundle exec rake release
81
- task :release => :build do
82
- system "git tag -a v#{BSON::VERSION} -m 'Tagging release: #{BSON::VERSION}'"
83
- system "git push --tags"
84
- if jruby?
85
- system "gem push bson-#{BSON::VERSION}-java.gem"
86
- system "rm bson-#{BSON::VERSION}-java.gem"
87
- else
88
- system "gem push bson-#{BSON::VERSION}.gem"
89
- system "rm bson-#{BSON::VERSION}.gem"
89
+ # overrides the default Bundler-provided `release` task, which also
90
+ # builds the gem. Our release process assumes the gem has already
91
+ # been built (and signed via GPG), so we just need `rake release` to
92
+ # push the gem to rubygems.
93
+ task :release do
94
+ require 'bson/version'
95
+
96
+ # confirm: there ought to be two gems, one for MRI, and one for Java. These
97
+ # will have been previously generated by the 'BSON Release' GitHub action.
98
+ gems = Dir['*.gem']
99
+ if gems.length != 2
100
+ abort "Expected two gem files to be ready to release; got #{gems.length}"
101
+ end
102
+
103
+ if ENV['GITHUB_ACTION'].nil?
104
+ abort <<~WARNING
105
+ `rake release` must be invoked from the `BSON Release` GitHub action,
106
+ and must not be invoked locally. This ensures the gem is properly signed
107
+ and distributed by the appropriate user.
108
+
109
+ Note that it is the `rubygems/release-gem@v1` step in the `BSON Release`
110
+ action that invokes this task. Do not rename or remove this task, or the
111
+ release-gem step will fail. Reimplement this task with caution.
112
+
113
+ NO GEMS were pushed to RubyGems.
114
+ WARNING
115
+ end
116
+
117
+ gems.each do |gem|
118
+ system 'gem', 'push', gem
90
119
  end
91
120
  end
92
121
 
93
122
  namespace :benchmark do
94
123
 
95
- task :ruby => :clean_all do
124
+ task :prep do
125
+ require_relative "perf/bench"
126
+ end
127
+
128
+ task ruby: [ :clean_all, 'benchmark:prep' ] do
96
129
  puts "Benchmarking pure Ruby..."
97
- require "bson"
98
130
  benchmark!
99
131
  end
100
132
 
101
- task :native => :compile do
133
+ task native: [ :compile, 'benchmark:prep' ] do
102
134
  puts "Benchmarking with native extensions..."
103
- require "bson"
104
135
  benchmark!
105
136
  end
106
137
 
107
138
  namespace :decimal128 do
108
-
109
- task :from_string do
139
+ task from_string: 'benchmark:prep' do
110
140
  puts "Benchmarking creating Decimal128 objects from a string"
111
- require 'bson'
112
141
  benchmark_decimal128_from_string!
113
142
  end
114
143
 
115
- task :to_string do
144
+ task to_string: 'benchmark:prep' do
116
145
  puts "Benchmarking getting a string representation of a Decimal128"
117
- require 'bson'
118
146
  benchmark_decimal128_to_string!
119
147
  end
120
148
  end
@@ -128,6 +156,7 @@ task :docs => 'docs:yard'
128
156
  namespace :docs do
129
157
  desc "Generate yard documention"
130
158
  task :yard do
159
+ require 'bson/version'
131
160
  out = File.join('yard-docs', BSON::VERSION)
132
161
  FileUtils.rm_rf(out)
133
162
  system "yardoc -o #{out} --title bson-#{BSON::VERSION}"
@@ -17,6 +17,7 @@
17
17
  #include <ruby.h>
18
18
  #include <stdbool.h>
19
19
  #include <stdint.h>
20
+ #include <stdlib.h>
20
21
  #include <unistd.h>
21
22
  #include <time.h>
22
23
  #include "bson-endian.h"
@@ -91,14 +92,16 @@ VALUE rb_bson_byte_buffer_put_uint32(VALUE self, VALUE i);
91
92
  VALUE rb_bson_byte_buffer_put_int64(VALUE self, VALUE i);
92
93
  VALUE rb_bson_byte_buffer_put_string(VALUE self, VALUE string);
93
94
  VALUE rb_bson_byte_buffer_put_symbol(VALUE self, VALUE symbol);
94
- VALUE rb_bson_byte_buffer_put_hash(VALUE self, VALUE hash, VALUE validating_keys);
95
- VALUE rb_bson_byte_buffer_put_array(VALUE self, VALUE array, VALUE validating_keys);
95
+ VALUE rb_bson_byte_buffer_put_hash(VALUE self, VALUE hash);
96
+ VALUE rb_bson_byte_buffer_put_array(VALUE self, VALUE array);
96
97
  VALUE rb_bson_byte_buffer_read_position(VALUE self);
97
98
  VALUE rb_bson_byte_buffer_replace_int32(VALUE self, VALUE index, VALUE i);
98
99
  VALUE rb_bson_byte_buffer_rewind(VALUE self);
99
100
  VALUE rb_bson_byte_buffer_write_position(VALUE self);
100
101
  VALUE rb_bson_byte_buffer_to_s(VALUE self);
102
+
101
103
  VALUE rb_bson_object_id_generator_next(int argc, VALUE* args, VALUE self);
104
+ VALUE rb_bson_object_id_generator_reset_counter(int argc, VALUE* args, VALUE self);
102
105
 
103
106
  size_t rb_bson_byte_buffer_memsize(const void *ptr);
104
107
  void rb_bson_byte_buffer_free(void *ptr);
@@ -113,6 +116,13 @@ VALUE pvt_const_get_3(const char *c1, const char *c2, const char *c3);
113
116
 
114
117
  int pvt_get_mode_option(int argc, VALUE *argv);
115
118
 
119
+ #define BSON_OBJECT_ID_RANDOM_VALUE_LENGTH ( 5 )
120
+
121
+ uint8_t* pvt_get_object_id_random_value();
122
+ void pvt_init_rand();
123
+ void pvt_rand_buf(uint8_t* bytes, int len, int pid);
124
+ int pvt_rand();
125
+
116
126
  /**
117
127
  * The counter for incrementing object ids.
118
128
  */
@@ -120,8 +130,6 @@ extern uint32_t rb_bson_object_id_counter;
120
130
 
121
131
  extern VALUE rb_bson_registry;
122
132
 
123
- extern VALUE rb_bson_illegal_key;
124
-
125
133
  extern const rb_data_type_t rb_byte_buffer_data_type;
126
134
 
127
135
  extern VALUE _ref_str, _id_str, _db_str;
data/ext/bson/extconf.rb CHANGED
@@ -1,3 +1,8 @@
1
- require "mkmf"
2
- $CFLAGS << " -Wall -g -std=c99"
3
- create_makefile("bson_native")
1
+ # frozen_string_literal: true
2
+ # rubocop:disable all
3
+
4
+ require 'mkmf'
5
+
6
+ $CFLAGS << ' -Wall -g -std=c99'
7
+
8
+ create_makefile('bson_native')
data/ext/bson/init.c CHANGED
@@ -23,8 +23,6 @@ uint32_t rb_bson_object_id_counter;
23
23
 
24
24
  VALUE rb_bson_registry;
25
25
 
26
- VALUE rb_bson_illegal_key;
27
-
28
26
  const rb_data_type_t rb_byte_buffer_data_type = {
29
27
  "bson/byte_buffer",
30
28
  { NULL, rb_bson_byte_buffer_free, rb_bson_byte_buffer_memsize }
@@ -46,6 +44,8 @@ void Init_bson_native()
46
44
  _db_str = rb_str_new_cstr("$db");
47
45
  rb_gc_register_mark_object(_db_str);
48
46
 
47
+ rb_require("digest/md5");
48
+
49
49
  VALUE rb_bson_module = rb_define_module("BSON");
50
50
 
51
51
  /* Document-class: BSON::ByteBuffer
@@ -60,9 +60,6 @@ void Init_bson_native()
60
60
  VALUE rb_digest_class = rb_const_get(rb_cObject, rb_intern("Digest"));
61
61
  VALUE rb_md5_class = rb_const_get(rb_digest_class, rb_intern("MD5"));
62
62
 
63
- rb_bson_illegal_key = rb_const_get(rb_const_get(rb_bson_module, rb_intern("String")),rb_intern("IllegalKey"));
64
- rb_gc_register_mark_object(rb_bson_illegal_key);
65
-
66
63
  rb_define_alloc_func(rb_byte_buffer_class, rb_bson_byte_buffer_allocate);
67
64
  rb_define_method(rb_byte_buffer_class, "initialize", rb_bson_byte_buffer_initialize, -1);
68
65
 
@@ -116,7 +113,7 @@ void Init_bson_native()
116
113
  rb_define_method(rb_byte_buffer_class, "get_array", rb_bson_byte_buffer_get_array, -1);
117
114
 
118
115
  rb_define_method(rb_byte_buffer_class, "get_int32", rb_bson_byte_buffer_get_int32, 0);
119
-
116
+
120
117
  /*
121
118
  * call-seq:
122
119
  * buffer.get_uint32(buffer) -> Fixnum
@@ -285,13 +282,13 @@ void Init_bson_native()
285
282
 
286
283
  /*
287
284
  * call-seq:
288
- * buffer.put_hash(hash, validating_keys) -> ByteBuffer
285
+ * buffer.put_hash(hash) -> ByteBuffer
289
286
  *
290
287
  * Writes a Hash into the byte buffer.
291
288
  *
292
289
  * Returns the modified +self+.
293
290
  */
294
- rb_define_method(rb_byte_buffer_class, "put_hash", rb_bson_byte_buffer_put_hash, 2);
291
+ rb_define_method(rb_byte_buffer_class, "put_hash", rb_bson_byte_buffer_put_hash, 1);
295
292
 
296
293
  /*
297
294
  * call-seq:
@@ -301,7 +298,7 @@ void Init_bson_native()
301
298
  *
302
299
  * Returns the modified +self+.
303
300
  */
304
- rb_define_method(rb_byte_buffer_class, "put_array", rb_bson_byte_buffer_put_array, 2);
301
+ rb_define_method(rb_byte_buffer_class, "put_array", rb_bson_byte_buffer_put_array, 1);
305
302
 
306
303
  /*
307
304
  * call-seq:
@@ -349,6 +346,7 @@ void Init_bson_native()
349
346
  rb_define_method(rb_byte_buffer_class, "to_s", rb_bson_byte_buffer_to_s, 0);
350
347
 
351
348
  rb_define_method(rb_bson_object_id_generator_class, "next_object_id", rb_bson_object_id_generator_next, -1);
349
+ rb_define_method(rb_bson_object_id_generator_class, "reset_counter", rb_bson_object_id_generator_reset_counter, -1);
352
350
 
353
351
  // Get the object id machine id and hash it.
354
352
  rb_require("digest/md5");
@@ -356,8 +354,10 @@ void Init_bson_native()
356
354
  rb_bson_machine_id[255] = '\0';
357
355
  rb_bson_generate_machine_id(rb_md5_class, rb_bson_machine_id);
358
356
 
359
- // Set the object id counter to a random number
360
- rb_bson_object_id_counter = FIX2INT(rb_funcall(rb_mKernel, rb_intern("rand"), 1, INT2FIX(0x1000000)));
357
+ pvt_init_rand();
358
+
359
+ // Set the object id counter to a random 3-byte integer
360
+ rb_bson_object_id_counter = pvt_rand() % 0xFFFFFF;
361
361
 
362
362
  rb_bson_registry = rb_const_get(rb_bson_module, rb_intern("Registry"));
363
363
  rb_gc_register_mark_object(rb_bson_registry);
data/ext/bson/read.c CHANGED
@@ -29,6 +29,7 @@ static VALUE pvt_get_symbol(byte_buffer_t *b, VALUE rb_buffer, int argc, VALUE *
29
29
  static VALUE pvt_get_boolean(byte_buffer_t *b);
30
30
  static VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type, int argc, VALUE *argv);
31
31
  static void pvt_skip_cstring(byte_buffer_t *b);
32
+ static size_t pvt_strnlen(const byte_buffer_t *b);
32
33
 
33
34
  void pvt_raise_decode_error(volatile VALUE msg) {
34
35
  VALUE klass = pvt_const_get_3("BSON", "Error", "BSONDecodeError");
@@ -80,8 +81,23 @@ VALUE pvt_read_field(byte_buffer_t *b, VALUE rb_buffer, uint8_t type, int argc,
80
81
  case BSON_TYPE_BOOLEAN: return pvt_get_boolean(b);
81
82
  default:
82
83
  {
83
- VALUE klass = rb_funcall(rb_bson_registry,rb_intern("get"),1, INT2FIX(type));
84
- VALUE value = rb_funcall(klass, rb_intern("from_bson"),1, rb_buffer);
84
+ VALUE klass = rb_funcall(rb_bson_registry, rb_intern("get"), 1, INT2FIX(type));
85
+ VALUE value;
86
+ if (argc > 1) {
87
+ rb_raise(rb_eArgError, "At most one argument is allowed");
88
+ } else if (argc > 0) {
89
+ VALUE call_args[2];
90
+ call_args[0] = rb_buffer;
91
+ Check_Type(argv[0], T_HASH);
92
+ call_args[1] = argv[0];
93
+ #ifdef RB_PASS_KEYWORDS /* Ruby 2.7+ */
94
+ value = rb_funcallv_kw(klass, rb_intern("from_bson"), 2, call_args, RB_PASS_KEYWORDS);
95
+ #else /* Ruby 2.6 and below */
96
+ value = rb_funcallv(klass, rb_intern("from_bson"), 2, call_args);
97
+ #endif
98
+ } else {
99
+ value = rb_funcall(klass, rb_intern("from_bson"), 1, rb_buffer);
100
+ }
85
101
  RB_GC_GUARD(klass);
86
102
  return value;
87
103
  }
@@ -128,7 +144,7 @@ VALUE rb_bson_byte_buffer_get_bytes(VALUE self, VALUE i)
128
144
  }
129
145
 
130
146
  VALUE pvt_get_boolean(byte_buffer_t *b){
131
- VALUE result;
147
+ VALUE result = Qnil;
132
148
  char byte_value;
133
149
  ENSURE_BSON_READ(b, 1);
134
150
  byte_value = *READ_PTR(b);
@@ -221,7 +237,7 @@ VALUE rb_bson_byte_buffer_get_cstring(VALUE self)
221
237
  int length;
222
238
 
223
239
  TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
224
- length = (int)strlen(READ_PTR(b));
240
+ length = (int)pvt_strnlen(b);
225
241
  ENSURE_BSON_READ(b, length);
226
242
  string = rb_enc_str_new(READ_PTR(b), length, rb_utf8_encoding());
227
243
  b->read_position += length + 1;
@@ -234,7 +250,7 @@ VALUE rb_bson_byte_buffer_get_cstring(VALUE self)
234
250
  void pvt_skip_cstring(byte_buffer_t *b)
235
251
  {
236
252
  int length;
237
- length = (int)strlen(READ_PTR(b));
253
+ length = (int)pvt_strnlen(b);
238
254
  ENSURE_BSON_READ(b, length);
239
255
  b->read_position += length + 1;
240
256
  }
@@ -366,17 +382,17 @@ static int pvt_is_dbref(VALUE doc) {
366
382
  if (NIL_P(ref) || !RB_TYPE_P(ref, T_STRING)) {
367
383
  return 0;
368
384
  }
369
-
385
+
370
386
  id = rb_hash_aref(doc, _id_str);
371
387
  if (NIL_P(id)) {
372
388
  return 0;
373
389
  }
374
-
390
+
375
391
  db = rb_hash_aref(doc, _db_str);
376
392
  if (!NIL_P(db) && !RB_TYPE_P(db, T_STRING)) {
377
393
  return 0;
378
394
  }
379
-
395
+
380
396
  return 1;
381
397
  }
382
398
 
@@ -404,7 +420,7 @@ VALUE rb_bson_byte_buffer_get_hash(int argc, VALUE *argv, VALUE self){
404
420
  if (READ_PTR(b) - start_ptr != length) {
405
421
  pvt_raise_decode_error(rb_sprintf("Expected to read %d bytes for the hash but read %ld bytes", length, READ_PTR(b) - start_ptr));
406
422
  }
407
-
423
+
408
424
  if (pvt_is_dbref(doc)) {
409
425
  VALUE cDBRef = pvt_const_get_2("BSON", "DBRef");
410
426
  doc = rb_funcall(cDBRef, rb_intern("new"), 1, doc);
@@ -438,3 +454,17 @@ VALUE rb_bson_byte_buffer_get_array(int argc, VALUE *argv, VALUE self){
438
454
 
439
455
  return array;
440
456
  }
457
+
458
+ /**
459
+ * Returns the length of the given string `str`. If no null-terminating byte
460
+ * is present when `len` bytes have been scanned, then `len` is
461
+ * returned.
462
+ */
463
+ size_t pvt_strnlen(const byte_buffer_t *b) {
464
+ const char *ptr = memchr(READ_PTR(b), '\0', READ_SIZE(b));
465
+
466
+ if (!ptr)
467
+ rb_raise(rb_eRangeError, "string is too long (possibly not null-terminated)");
468
+
469
+ return (size_t)(ptr - READ_PTR(b));
470
+ }