bson 5.0.0 → 5.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +91 -7
  3. data/Rakefile +63 -39
  4. data/ext/bson/read.c +18 -3
  5. data/ext/bson/util.c +5 -2
  6. data/ext/bson/write.c +4 -0
  7. data/lib/bson/array.rb +1 -1
  8. data/lib/bson/binary.rb +16 -1
  9. data/lib/bson/code.rb +1 -1
  10. data/lib/bson/code_with_scope.rb +1 -1
  11. data/lib/bson/db_pointer.rb +1 -1
  12. data/lib/bson/decimal128/builder.rb +1 -1
  13. data/lib/bson/decimal128.rb +1 -1
  14. data/lib/bson/ext_json.rb +1 -1
  15. data/lib/bson/float.rb +1 -1
  16. data/lib/bson/hash.rb +1 -1
  17. data/lib/bson/int32.rb +1 -1
  18. data/lib/bson/int64.rb +1 -1
  19. data/lib/bson/integer.rb +1 -1
  20. data/lib/bson/max_key.rb +1 -1
  21. data/lib/bson/min_key.rb +1 -1
  22. data/lib/bson/object.rb +2 -2
  23. data/lib/bson/object_id.rb +12 -2
  24. data/lib/bson/regexp.rb +1 -1
  25. data/lib/bson/symbol.rb +2 -2
  26. data/lib/bson/time.rb +1 -1
  27. data/lib/bson/timestamp.rb +1 -1
  28. data/lib/bson/undefined.rb +1 -1
  29. data/lib/bson/version.rb +2 -1
  30. data/spec/bson/binary_spec.rb +46 -7
  31. data/spec/bson/object_id_spec.rb +14 -0
  32. metadata +7 -80
  33. checksums.yaml.gz.sig +0 -0
  34. data/spec/shared/LICENSE +0 -20
  35. data/spec/shared/bin/get-mongodb-download-url +0 -17
  36. data/spec/shared/bin/s3-copy +0 -45
  37. data/spec/shared/bin/s3-upload +0 -69
  38. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  39. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  40. data/spec/shared/lib/mrss/constraints.rb +0 -378
  41. data/spec/shared/lib/mrss/docker_runner.rb +0 -298
  42. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  43. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  44. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  45. data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
  46. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  47. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  48. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  49. data/spec/shared/lib/mrss/utils.rb +0 -37
  50. data/spec/shared/share/Dockerfile.erb +0 -321
  51. data/spec/shared/share/haproxy-1.conf +0 -16
  52. data/spec/shared/share/haproxy-2.conf +0 -17
  53. data/spec/shared/shlib/config.sh +0 -27
  54. data/spec/shared/shlib/distro.sh +0 -74
  55. data/spec/shared/shlib/server.sh +0 -416
  56. data/spec/shared/shlib/set_env.sh +0 -169
  57. data.tar.gz.sig +0 -0
  58. metadata.gz.sig +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12132ecbf12cd3f9d72a97a4131985275206bd493afd61b38f723111e4f3d564
4
- data.tar.gz: bbde2fa0d1b0cf9114a9c03ae971ecda873508602270d6ce4e9cc07052a73ba1
3
+ metadata.gz: 41a002d14b035c9cf01534ee489ca61c012202aac1e2729fa850960c359ba5cd
4
+ data.tar.gz: f63478ad673c6dfbed91eaed8477b45287a264fa6c06e29d2273c41a0951e4e1
5
5
  SHA512:
6
- metadata.gz: 75d4fc461601cb54b33371441414a35762578c4620ebd28301649bd8ff564fe41a495055c6cda98b2b61f7ef3678f6375e3e89eebeea23cd0736f7ed4b93a525
7
- data.tar.gz: 5a64b2fca65a1117fbac73d68144387d5f0a4bc6737f0533926f2e2af5ac02a6bf9393f0307bdf17ca085380d1b14234fad1bba3103e8f64e1868bda2840491d
6
+ metadata.gz: 67721ba06f0154a5dc37bc460602f878843243706e0194375c0350a095774beb06ba7a5b861b137d95bd0e753ed74b35d3b541283864aaec02b61dd94952d9ed
7
+ data.tar.gz: 525cc2a1da23ceaec40243cf7cc9ab504e81c11b56bf22e9f51f156c24294231fcd300874ae3b22c80fa473be568d84d43c627eabd4434c3895458c332364f6a
data/README.md CHANGED
@@ -1,16 +1,54 @@
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.6) and JRuby (9.2+).
51
+ BSON is tested against MRI (2.7+) and JRuby (9.3+).
14
52
 
15
53
  Documentation
16
54
  -------------
@@ -29,6 +67,56 @@ BSON Specification
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
@@ -47,28 +47,37 @@ else
47
47
  end
48
48
  end
49
49
 
50
- require "bson/version"
50
+ RSpec::Core::RakeTask.new(:rspec)
51
51
 
52
- def extension
53
- 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"
54
56
  end
55
57
 
56
- require_relative "perf/bench"
57
-
58
- 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
59
66
 
60
- if jruby?
61
- task :build => [ :clean_all, :compile ] do
62
- system "gem build bson.gemspec"
63
- end
64
- else
65
- task :build => :clean_all do
66
- system "gem build bson.gemspec"
67
- 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"
68
76
  end
69
77
 
70
78
  task :clean_all => :clean do
71
- 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"))
72
81
  FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson_native.o"))
73
82
  FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', "bson-ruby.jar"))
74
83
  end
@@ -77,49 +86,63 @@ task :spec => :compile do
77
86
  Rake::Task["rspec"].invoke
78
87
  end
79
88
 
80
- # Run bundle exec rake release with mri and jruby. Ex:
81
- #
82
- # rvm use 2.1.0@bson
83
- # bundle exec rake release
84
- # rvm use jruby@bson
85
- # bundle exec rake release
86
- task :release => :build do
87
- system "git tag -a v#{BSON::VERSION} -m 'Tagging release: #{BSON::VERSION}'"
88
- system "git push --tags"
89
- if jruby?
90
- system "gem push bson-#{BSON::VERSION}-java.gem"
91
- system "rm bson-#{BSON::VERSION}-java.gem"
92
- else
93
- system "gem push bson-#{BSON::VERSION}.gem"
94
- 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
95
119
  end
96
120
  end
97
121
 
98
122
  namespace :benchmark do
99
123
 
100
- 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
101
129
  puts "Benchmarking pure Ruby..."
102
- require "bson"
103
130
  benchmark!
104
131
  end
105
132
 
106
- task :native => :compile do
133
+ task native: [ :compile, 'benchmark:prep' ] do
107
134
  puts "Benchmarking with native extensions..."
108
- require "bson"
109
135
  benchmark!
110
136
  end
111
137
 
112
138
  namespace :decimal128 do
113
-
114
- task :from_string do
139
+ task from_string: 'benchmark:prep' do
115
140
  puts "Benchmarking creating Decimal128 objects from a string"
116
- require 'bson'
117
141
  benchmark_decimal128_from_string!
118
142
  end
119
143
 
120
- task :to_string do
144
+ task to_string: 'benchmark:prep' do
121
145
  puts "Benchmarking getting a string representation of a Decimal128"
122
- require 'bson'
123
146
  benchmark_decimal128_to_string!
124
147
  end
125
148
  end
@@ -133,6 +156,7 @@ task :docs => 'docs:yard'
133
156
  namespace :docs do
134
157
  desc "Generate yard documention"
135
158
  task :yard do
159
+ require 'bson/version'
136
160
  out = File.join('yard-docs', BSON::VERSION)
137
161
  FileUtils.rm_rf(out)
138
162
  system "yardoc -o #{out} --title bson-#{BSON::VERSION}"
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");
@@ -143,7 +144,7 @@ VALUE rb_bson_byte_buffer_get_bytes(VALUE self, VALUE i)
143
144
  }
144
145
 
145
146
  VALUE pvt_get_boolean(byte_buffer_t *b){
146
- VALUE result;
147
+ VALUE result = Qnil;
147
148
  char byte_value;
148
149
  ENSURE_BSON_READ(b, 1);
149
150
  byte_value = *READ_PTR(b);
@@ -236,7 +237,7 @@ VALUE rb_bson_byte_buffer_get_cstring(VALUE self)
236
237
  int length;
237
238
 
238
239
  TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
239
- length = (int)strlen(READ_PTR(b));
240
+ length = (int)pvt_strnlen(b);
240
241
  ENSURE_BSON_READ(b, length);
241
242
  string = rb_enc_str_new(READ_PTR(b), length, rb_utf8_encoding());
242
243
  b->read_position += length + 1;
@@ -249,7 +250,7 @@ VALUE rb_bson_byte_buffer_get_cstring(VALUE self)
249
250
  void pvt_skip_cstring(byte_buffer_t *b)
250
251
  {
251
252
  int length;
252
- length = (int)strlen(READ_PTR(b));
253
+ length = (int)pvt_strnlen(b);
253
254
  ENSURE_BSON_READ(b, length);
254
255
  b->read_position += length + 1;
255
256
  }
@@ -453,3 +454,17 @@ VALUE rb_bson_byte_buffer_get_array(int argc, VALUE *argv, VALUE self){
453
454
 
454
455
  return array;
455
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
+ }
data/ext/bson/util.c CHANGED
@@ -43,7 +43,7 @@ void rb_bson_generate_machine_id(VALUE rb_md5_class, char *rb_bson_machine_id)
43
43
  * Generate the next object id.
44
44
  *
45
45
  * Specification:
46
- * https://github.com/mongodb/specifications/blob/master/source/objectid.rst
46
+ * https://github.com/mongodb/specifications/blob/master/source/bson-objectid/objectid.md
47
47
  *
48
48
  * The ObjectID BSON type is a 12-byte value consisting of three different portions (fields):
49
49
  * * a 4-byte value representing the seconds since the Unix epoch in the highest order bytes,
@@ -65,7 +65,7 @@ VALUE rb_bson_object_id_generator_next(int argc, VALUE* args, VALUE self)
65
65
  * obtaining the timestamp value." */
66
66
 
67
67
  timestamp = rb_funcall(rb_bson_object_id_class, rb_intern("timestamp"), 0);
68
- time_component = BSON_UINT32_TO_BE(NUM2INT(timestamp));
68
+ time_component = BSON_UINT32_TO_BE(NUM2UINT(timestamp));
69
69
 
70
70
  /* "A 5-byte field consisting of a random value generated once per process.
71
71
  * This random value is unique to the machine and process.
@@ -170,6 +170,9 @@ VALUE pvt_load_secure_random(VALUE _arg) {
170
170
  pvt_SecureRandom = rb_const_get(rb_cObject, rb_intern("SecureRandom"));
171
171
  pvt_has_random_number = rb_respond_to(pvt_SecureRandom, rb_intern("random_number"));
172
172
 
173
+ // mark SecureRandom so it does not get moved
174
+ rb_global_variable(&pvt_SecureRandom);
175
+
173
176
  return Qnil;
174
177
  }
175
178
 
data/ext/bson/write.c CHANGED
@@ -633,6 +633,10 @@ void pvt_put_array_index(byte_buffer_t *b, int32_t index)
633
633
  c_str = buffer;
634
634
  snprintf(buffer, sizeof(buffer), "%d", index);
635
635
  }
636
+ // strlen is a potential vector for out-of-bounds errors, but
637
+ // the only way for that to happen here, specifically, is if `index`
638
+ // is greater than 10e16 - 1, which is far beyond the domain of an
639
+ // int32.
636
640
  length = strlen(c_str) + 1;
637
641
  ENSURE_BSON_WRITE(b, length);
638
642
  memcpy(WRITE_PTR(b), c_str, length);
data/lib/bson/array.rb CHANGED
@@ -92,7 +92,7 @@ module BSON
92
92
  end
93
93
 
94
94
  # Converts this object to a representation directly serializable to
95
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
95
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
96
96
  #
97
97
  # This method recursively invokes +as_extended_json+ with the provided
98
98
  # options on each array element.
data/lib/bson/binary.rb CHANGED
@@ -24,6 +24,7 @@ module BSON
24
24
  # @since 2.0.0
25
25
  class Binary
26
26
  include JSON
27
+ include Comparable
27
28
 
28
29
  # A binary is type 0x05 in the BSON spec.
29
30
  #
@@ -90,6 +91,20 @@ module BSON
90
91
  end
91
92
  alias eql? ==
92
93
 
94
+ # Compare this binary object to another object. The two objects must have
95
+ # the same type for any meaningful comparison.
96
+ #
97
+ # @param [ Object ] other The object to compare against.
98
+ #
99
+ # @return [ Integer | nil ] If the objects have the same type, the result
100
+ # is -1 if self < other, 0 if self == other, and 1 if self > other. If
101
+ # other is not a Binary, or is a Binary of a different type, returns nil.
102
+ def <=>(other)
103
+ return nil unless other.is_a?(Binary) && type == other.type
104
+
105
+ data <=> other.data
106
+ end
107
+
93
108
  # Generates a Fixnum hash value for this object.
94
109
  #
95
110
  # Allows using Binary as hash keys.
@@ -112,7 +127,7 @@ module BSON
112
127
  end
113
128
 
114
129
  # Converts this object to a representation directly serializable to
115
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
130
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
116
131
  #
117
132
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
118
133
  # (default is canonical extended JSON)
data/lib/bson/code.rb CHANGED
@@ -60,7 +60,7 @@ module BSON
60
60
  end
61
61
 
62
62
  # Converts this object to a representation directly serializable to
63
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
63
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
64
64
  #
65
65
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
66
66
  # (default is canonical extended JSON)
@@ -64,7 +64,7 @@ module BSON
64
64
  end
65
65
 
66
66
  # Converts this object to a representation directly serializable to
67
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
67
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
68
68
  #
69
69
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
70
70
  # (default is canonical extended JSON)
@@ -66,7 +66,7 @@ module BSON
66
66
  end
67
67
 
68
68
  # Converts this object to a representation directly serializable to
69
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
69
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
70
70
  #
71
71
  # @return [ Hash ] The extended json representation.
72
72
  def as_extended_json(**_options)
@@ -156,7 +156,7 @@ module BSON
156
156
  # @return [ Regex ] The regex for a valid decimal128 string.
157
157
  #
158
158
  # @since 4.2.0
159
- VALID_DECIMAL128_STRING_REGEX = /^[\-\+]?(\d+(\.\d*)?|\.\d+)(E[\-\+]?\d+)?$/i
159
+ VALID_DECIMAL128_STRING_REGEX = /\A[\-\+]?(\d+(\.\d*)?|\.\d+)(E[\-\+]?\d+)?\Z/i
160
160
 
161
161
  # Initialize the FromString Builder object.
162
162
  #
@@ -73,7 +73,7 @@ module BSON
73
73
  end
74
74
 
75
75
  # Converts this object to a representation directly serializable to
76
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
76
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
77
77
  #
78
78
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
79
79
  # (default is canonical extended JSON)
data/lib/bson/ext_json.rb CHANGED
@@ -19,7 +19,7 @@ require 'json'
19
19
  module BSON
20
20
 
21
21
  # This module contains methods for parsing Extended JSON 2.0.
22
- # https://github.com/mongodb/specifications/blob/master/source/extended-json.rst
22
+ # https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md
23
23
  module ExtJSON
24
24
 
25
25
  # Parses JSON in a string into a Ruby object tree.
data/lib/bson/float.rb CHANGED
@@ -49,7 +49,7 @@ module BSON
49
49
  end
50
50
 
51
51
  # Converts this object to a representation directly serializable to
52
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
52
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
53
53
  #
54
54
  # This method returns the float itself if relaxed representation is
55
55
  # requested and the value is finite, otherwise a $numberDouble hash.
data/lib/bson/hash.rb CHANGED
@@ -53,7 +53,7 @@ module BSON
53
53
  end
54
54
 
55
55
  # Converts this object to a representation directly serializable to
56
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
56
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
57
57
  #
58
58
  # This method recursively invokes +as_extended_json+ with the provided
59
59
  # options on each hash value.
data/lib/bson/int32.rb CHANGED
@@ -131,7 +131,7 @@ module BSON
131
131
  end
132
132
 
133
133
  # Converts this object to a representation directly serializable to
134
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
134
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
135
135
  #
136
136
  # This method returns the integer value if relaxed representation is
137
137
  # requested, otherwise a $numberInt hash.
data/lib/bson/int64.rb CHANGED
@@ -131,7 +131,7 @@ module BSON
131
131
  end
132
132
 
133
133
  # Converts this object to a representation directly serializable to
134
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
134
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
135
135
  #
136
136
  # This method returns the integer value if relaxed representation is
137
137
  # requested, otherwise a $numberLong hash.
data/lib/bson/integer.rb CHANGED
@@ -160,7 +160,7 @@ module BSON
160
160
  end
161
161
 
162
162
  # Converts this object to a representation directly serializable to
163
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
163
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
164
164
  #
165
165
  # This method returns the integer itself if relaxed representation is
166
166
  # requested, otherwise a $numberInt hash if the value fits in 32 bits
data/lib/bson/max_key.rb CHANGED
@@ -63,7 +63,7 @@ module BSON
63
63
  end
64
64
 
65
65
  # Converts this object to a representation directly serializable to
66
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
66
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
67
67
  #
68
68
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
69
69
  # (default is canonical extended JSON)
data/lib/bson/min_key.rb CHANGED
@@ -63,7 +63,7 @@ module BSON
63
63
  end
64
64
 
65
65
  # Converts this object to a representation directly serializable to
66
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
66
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
67
67
  #
68
68
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
69
69
  # (default is canonical extended JSON)
data/lib/bson/object.rb CHANGED
@@ -62,7 +62,7 @@ module BSON
62
62
  end
63
63
 
64
64
  # Serializes this object to Extended JSON
65
- # (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
65
+ # (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
66
66
  #
67
67
  # Subclasses should override +as_extended_json+ rather than this method.
68
68
  #
@@ -75,7 +75,7 @@ module BSON
75
75
  end
76
76
 
77
77
  # Converts this object to a representation directly serializable to
78
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
78
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
79
79
  #
80
80
  # Subclasses should override this method to provide custom serialization
81
81
  # to Extended JSON.
@@ -75,7 +75,7 @@ module BSON
75
75
  end
76
76
 
77
77
  # Converts this object to a representation directly serializable to
78
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
78
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
79
79
  #
80
80
  # @return [ Hash ] The extended json representation.
81
81
  def as_extended_json(**_)
@@ -356,12 +356,22 @@ module BSON
356
356
  block_given? ? yield(object) : object
357
357
  end
358
358
 
359
+ # The largest numeric value that can be converted to an integer by MRI's
360
+ # NUM2UINT. Further, the spec dictates that the time component of an
361
+ # ObjectID must be no more than 4 bytes long, so the spec itself is
362
+ # constrained in this regard.
363
+ MAX_INTEGER = 2 ** 32
364
+
359
365
  # Returns an integer timestamp (seconds since the Epoch). Primarily used
360
366
  # by the generator to produce object ids.
361
367
  #
368
+ # @note This value is guaranteed to be no more than 4 bytes in length. A
369
+ # time value far enough in the future to require a larger integer than
370
+ # 4 bytes will be truncated to 4 bytes.
371
+ #
362
372
  # @return [ Integer ] the number of seconds since the Epoch.
363
373
  def timestamp
364
- ::Time.now.to_i
374
+ ::Time.now.to_i % MAX_INTEGER
365
375
  end
366
376
  end
367
377
 
data/lib/bson/regexp.rb CHANGED
@@ -200,7 +200,7 @@ module BSON
200
200
  end
201
201
 
202
202
  # Converts this object to a representation directly serializable to
203
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
203
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
204
204
  #
205
205
  # @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
206
206
  # (default is canonical extended JSON)
data/lib/bson/symbol.rb CHANGED
@@ -89,7 +89,7 @@ module BSON
89
89
  end
90
90
 
91
91
  # Converts this object to a representation directly serializable to
92
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
92
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
93
93
  #
94
94
  # @return [ Hash ] The extended json representation.
95
95
  def as_extended_json(**_options)
@@ -166,7 +166,7 @@ module BSON
166
166
  end
167
167
 
168
168
  # Converts this object to a representation directly serializable to
169
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
169
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
170
170
  #
171
171
  # @return [ Hash ] The extended json representation.
172
172
  def as_extended_json(**_options)
data/lib/bson/time.rb CHANGED
@@ -61,7 +61,7 @@ module BSON
61
61
  end
62
62
 
63
63
  # Converts this object to a representation directly serializable to
64
- # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
64
+ # Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json/extended-json.md).
65
65
  #
66
66
  # @note The time is floored to the nearest millisecond.
67
67
  #