diff --git a/doc/language/globals.md b/doc/language/globals.md
index b9315f5ff975e4..b22363f1da1b71 100644
--- a/doc/language/globals.md
+++ b/doc/language/globals.md
@@ -14,70 +14,72 @@ require 'English'
### Exceptions
-| Variable | English | Contains |
-|-------------|-------------------|----------------------------------------------------|
-| `$!` | `$ERROR_INFO` | Exception object; set by Kernel#raise. |
-| `$@` | `$ERROR_POSITION` | Array of backtrace positions; set by Kernel#raise. |
+| Variable | English | Contains |
+|:--------:|:-----------------:|----------------------------------------------------|
+| `$!` | `$ERROR_INFO` | Exception object; set by Kernel#raise. |
+| `$@` | `$ERROR_POSITION` | Array of backtrace positions; set by Kernel#raise. |
### Pattern Matching
-| Variable | English | Contains |
-|---------------|---------------------|--------------------------------------------------|
-| `$~` | `$LAST_MATCH_INFO` | MatchData object; set by matcher method. |
-| `$&` | `$MATCH` | Matched substring; set by matcher method. |
-| `` $` `` | `$PRE_MATCH` | Substring left of match; set by matcher method. |
-| `$'` | `$POST_MATCH` | Substring right of match; set by matcher method. |
-| `$+` | `$LAST_PAREN_MATCH` | Last group matched; set by matcher method. |
-| `$1` | | First group matched; set by matcher method. |
-| `$2` | | Second group matched; set by matcher method. |
+| Variable | English | Contains |
+|:-------------:|:-------------------:|--------------------------------------------------|
+| `$~` | `$LAST_MATCH_INFO` | MatchData object; set by matcher method. |
+| `$&` | `$MATCH` | Matched substring; set by matcher method. |
+| `` $` `` | `$PRE_MATCH` | Substring left of match; set by matcher method. |
+| `$'` | `$POST_MATCH` | Substring right of match; set by matcher method. |
+| `$+` | `$LAST_PAREN_MATCH` | Last group matched; set by matcher method. |
+| `$1` | | First group matched; set by matcher method. |
+| `$2` | | Second group matched; set by matcher method. |
| $_n_ | | nth group matched; set by matcher method. |
### Separators
-| Variable | English | Contains |
-|----------|----------------------------|--------------------------------------------|
-| `$/` | `$INPUT_RECORD_SEPARATOR` | Input record separator; initially newline. |
-| `$\` | `$OUTPUT_RECORD_SEPARATOR` | Output record separator; initially `nil`. |
+| Variable | English | Contains |
+|:-----------:|:--------------------------:|--------------------------------------------|
+| `$/`, `$-0` | `$INPUT_RECORD_SEPARATOR` | Input record separator; initially newline. |
+| `$\` | `$OUTPUT_RECORD_SEPARATOR` | Output record separator; initially `nil`. |
### Streams
-| Variable | English | Contains |
-|-----------|-----------------------------|-----------------------------------------------|
+| Variable | English | Contains |
+|:---------:|:---------------------------:|-----------------------------------------------|
| `$stdin` | | Standard input stream; initially `STDIN`. |
| `$stdout` | | Standard input stream; initially `STDIOUT`. |
| `$stderr` | | Standard input stream; initially `STDERR`. |
-| `$<` | `$DEFAULT_INPUT` | Default standard input; `ARGF` or `$stdin`. |
-| `$>` | `$DEFAULT_OUTPUT` | Default standard output; initially `$stdout`. |
-| `$.` | `$INPUT_LINE_NUMBER`, `$NR` | Input position of most recently read stream. |
-| `$_` | `$LAST_READ_LINE` | String from most recently read stream. |
+| `$<` | `$DEFAULT_INPUT` | Default standard input; `ARGF` or `$stdin`. |
+| `$>` | `$DEFAULT_OUTPUT` | Default standard output; initially `$stdout`. |
+| `$.` | `$INPUT_LINE_NUMBER`, `$NR` | Input position of most recently read stream. |
+| `$_` | `$LAST_READ_LINE` | String from most recently read stream. |
### Processes
-| Variable | English | Contains |
-|---------------------------|-----------------------|--------------------------------------------------------|
-| `$0` | | Initially, the name of the executing program. |
-| `$*` | `$ARGV` | Points to the `ARGV` array. |
-| `$$` | `$PROCESS_ID`, `$PID` | Process ID of the current process. |
-| `$?` | `$CHILD_STATUS` | Process::Status of most recently exited child process. |
+| Variable | English | Contains |
+|:-------------------------:|:---------------------:|--------------------------------------------------------|
+| `$0` | | Initially, the name of the executing program. |
+| `$*` | `$ARGV` | Points to the `ARGV` array. |
+| `$$` | `$PROCESS_ID`, `$PID` | Process ID of the current process. |
+| `$?` | `$CHILD_STATUS` | Process::Status of most recently exited child process. |
| `$LOAD_PATH`, `$:`, `$-I` | | Array of paths to be searched. |
| `$LOADED_FEATURES`, `$"` | | Array of paths to loaded files. |
### Debugging
-| Variable | English | Contains |
-|-------------|---------|--------------------------------------------------------|
+| Variable | English | Contains |
+|:-----------:|:-------:|--------------------------------------------------------|
| `$FILENAME` | | The value returned by method ARGF.filename. |
-| `$DEBUG` | | Initially, whether option `-d` or `--debug` was given. |
+| `$DEBUG` | | Initially, whether option `-d` or `--debug` was given. |
| `$VERBOSE` | | Initially, whether option `-V` or `-W` was given. |
### Other Variables
-| Variable | English | Contains |
-|----------|---------|------------------------------------------------|
-| `$-a` | | Whether option `-a` was given. |
-| `$-i` | | Extension given with command-line option `-i`. |
-| `$-l` | | Whether option `-l` was given. |
-| `$-p` | | Whether option `-p` was given. |
+| Variable | English | Contains |
+|:-----------:|:-------:|------------------------------------------------|
+| `$-F`, `$;` | | Separator given with command-line option `-F`. |
+| `$-a` | | Whether option `-a` was given. |
+| `$-i` | | Extension given with command-line option `-i`. |
+| `$-l` | | Whether option `-l` was given. |
+| `$-p` | | Whether option `-p` was given. |
+| `$F` | | Array of `$_` split by `$-F`. |
## Exceptions
@@ -174,6 +176,10 @@ No \English.
### `$/` (Input Record Separator)
An input record separator, initially newline.
+Set by the command-line option `-0`.
+
+Setting to non-nil value by other than the command-line option is
+deprecated.
English - `$INPUT_RECORD_SEPARATOR`, `$RS`.
@@ -182,6 +188,10 @@ Aliased as `$-0`.
### `$\` (Output Record Separator)
An output record separator, initially `nil`.
+Copied from `$/` when the command-line option `-l` is given.
+
+Setting to non-nil value by other than the command-line option is
+deprecated.
English - `$OUTPUT_RECORD_SEPARATOR`, `$ORS`.
@@ -340,6 +350,16 @@ Aliased as `$-v` and `$-w`.
## Other Variables
+### `$-F`
+
+The default field separator in String#split; must be a String or a
+Regexp, and can be set with command-line option `-F`.
+
+Setting to non-nil value by other than the command-line option is
+deprecated.
+
+Aliased as `$;`.
+
### `$-a`
Whether command-line option `-a` was given; read-only.
@@ -359,14 +379,18 @@ Whether command-line option `-l` was set; read-only.
Whether command-line option `-p` was given; read-only.
+### `$F`
+
+If the command line option `-a` is given, the array obtained by
+splitting `$_` by `$-F` is assigned at the start of each `-l`/`-p`
+loop.
+
## Deprecated
### `$=`
### `$,`
-### `$;`
-
# Pre-Defined Global Constants
## Summary
@@ -374,34 +398,34 @@ Whether command-line option `-p` was given; read-only.
### Streams
| Constant | Contains |
-|----------|-------------------------|
+|:--------:|-------------------------|
| `STDIN` | Standard input stream. |
| `STDOUT` | Standard output stream. |
| `STDERR` | Standard error stream. |
### Environment
-| Constant | Contains |
-|-----------------------|-------------------------------------------------------------------------------|
-| `ENV` | Hash of current environment variable names and values. |
-| `ARGF` | String concatenation of files given on the command line, or `$stdin` if none. |
-| `ARGV` | Array of the given command-line arguments. |
-| `TOPLEVEL_BINDING` | Binding of the top level scope. |
-| `RUBY_VERSION` | String Ruby version. |
-| `RUBY_RELEASE_DATE` | String Ruby release date. |
-| `RUBY_PLATFORM` | String Ruby platform. |
-| `RUBY_PATCH_LEVEL` | String Ruby patch level. |
-| `RUBY_REVISION` | String Ruby revision. |
-| `RUBY_COPYRIGHT` | String Ruby copyright. |
-| `RUBY_ENGINE` | String Ruby engine. |
+| Constant | Contains |
+|:---------------------:|-------------------------------------------------------------------------------|
+| `ENV` | Hash of current environment variable names and values. |
+| `ARGF` | String concatenation of files given on the command line, or `$stdin` if none. |
+| `ARGV` | Array of the given command-line arguments. |
+| `TOPLEVEL_BINDING` | Binding of the top level scope. |
+| `RUBY_VERSION` | String Ruby version. |
+| `RUBY_RELEASE_DATE` | String Ruby release date. |
+| `RUBY_PLATFORM` | String Ruby platform. |
+| `RUBY_PATCH_LEVEL` | String Ruby patch level. |
+| `RUBY_REVISION` | String Ruby revision. |
+| `RUBY_COPYRIGHT` | String Ruby copyright. |
+| `RUBY_ENGINE` | String Ruby engine. |
| `RUBY_ENGINE_VERSION` | String Ruby engine version. |
-| `RUBY_DESCRIPTION` | String Ruby description. |
+| `RUBY_DESCRIPTION` | String Ruby description. |
### Embedded Data
| Constant | Contains |
-|----------|--------------------------------------------------------------------|
-| `DATA` | File containing embedded data (lines following `__END__`, if any). |
+|:--------:|--------------------------------------------------------------------|
+| `DATA` | File containing embedded data (lines following `__END__`, if any). |
## Streams
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c
index cb13ac6ecf876d..b21a79484ccc4a 100644
--- a/ext/openssl/ossl_asn1.c
+++ b/ext/openssl/ossl_asn1.c
@@ -9,64 +9,81 @@
*/
#include "ossl.h"
-static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
- int depth, int yield, long *num_read);
-static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
+/********/
+/*
+ * ASN1 module
+ */
+#define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
+#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
+#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
+#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
+#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH)
+
+#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
+#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
+#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
+#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
+#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))
+
+VALUE mASN1;
+static VALUE eASN1Error;
+
+VALUE cASN1Data;
+static VALUE cASN1Primitive;
+static VALUE cASN1Constructive;
+
+static VALUE cASN1EndOfContent;
+static VALUE cASN1Boolean; /* BOOLEAN */
+static VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
+static VALUE cASN1BitString; /* BIT STRING */
+static VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */
+static VALUE cASN1NumericString, cASN1PrintableString;
+static VALUE cASN1T61String, cASN1VideotexString;
+static VALUE cASN1IA5String, cASN1GraphicString;
+static VALUE cASN1ISO64String, cASN1GeneralString;
+static VALUE cASN1UniversalString, cASN1BMPString;
+static VALUE cASN1Null; /* NULL */
+static VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */
+static VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */
+static VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
+
+static VALUE sym_IMPLICIT, sym_EXPLICIT;
+static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
+static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
+static ID id_each;
/*
* DATE conversion
*/
+static VALUE
+time_utc_new(VALUE args)
+{
+ return rb_funcallv(rb_cTime, rb_intern("utc"), 6, (VALUE *)args);
+}
+
+static VALUE
+time_utc_new_rescue(VALUE args, VALUE exc)
+{
+ rb_raise(eASN1Error, "invalid time");
+}
+
VALUE
asn1time_to_time(const ASN1_TIME *time)
{
struct tm tm;
- VALUE argv[6];
- int count;
-
- memset(&tm, 0, sizeof(struct tm));
-
- switch (time->type) {
- case V_ASN1_UTCTIME:
- count = sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ",
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
- &tm.tm_sec);
-
- if (count == 5) {
- tm.tm_sec = 0;
- } else if (count != 6) {
- ossl_raise(rb_eTypeError, "bad UTCTIME format: \"%s\"",
- time->data);
- }
- if (tm.tm_year < 50) {
- tm.tm_year += 2000;
- } else {
- tm.tm_year += 1900;
- }
- break;
- case V_ASN1_GENERALIZEDTIME:
- count = sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ",
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
- &tm.tm_sec);
- if (count == 5) {
- tm.tm_sec = 0;
- }
- else if (count != 6) {
- ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format: \"%s\"",
- time->data);
- }
- break;
- default:
- rb_warning("unknown time format");
- return Qnil;
- }
- argv[0] = INT2NUM(tm.tm_year);
- argv[1] = INT2NUM(tm.tm_mon);
- argv[2] = INT2NUM(tm.tm_mday);
- argv[3] = INT2NUM(tm.tm_hour);
- argv[4] = INT2NUM(tm.tm_min);
- argv[5] = INT2NUM(tm.tm_sec);
-
- return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv);
+ if (!ASN1_TIME_to_tm(time, &tm))
+ ossl_raise(eASN1Error, "ASN1_TIME_to_tm");
+
+ VALUE args[] = {
+ INT2NUM(tm.tm_year + 1900),
+ INT2NUM(tm.tm_mon + 1),
+ INT2NUM(tm.tm_mday),
+ INT2NUM(tm.tm_hour),
+ INT2NUM(tm.tm_min),
+ INT2NUM(tm.tm_sec),
+ };
+ return rb_rescue2(time_utc_new, (VALUE)args, time_utc_new_rescue, Qnil,
+ rb_eArgError, 0);
}
static VALUE
@@ -190,49 +207,6 @@ ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *obj)
return ossl_asn1obj_to_string_oid(obj);
}
-/********/
-/*
- * ASN1 module
- */
-#define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
-#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
-#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
-#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
-#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH)
-
-#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
-#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
-#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
-#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
-#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))
-
-VALUE mASN1;
-static VALUE eASN1Error;
-
-VALUE cASN1Data;
-static VALUE cASN1Primitive;
-static VALUE cASN1Constructive;
-
-static VALUE cASN1EndOfContent;
-static VALUE cASN1Boolean; /* BOOLEAN */
-static VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
-static VALUE cASN1BitString; /* BIT STRING */
-static VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */
-static VALUE cASN1NumericString, cASN1PrintableString;
-static VALUE cASN1T61String, cASN1VideotexString;
-static VALUE cASN1IA5String, cASN1GraphicString;
-static VALUE cASN1ISO64String, cASN1GeneralString;
-static VALUE cASN1UniversalString, cASN1BMPString;
-static VALUE cASN1Null; /* NULL */
-static VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */
-static VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */
-static VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
-
-static VALUE sym_IMPLICIT, sym_EXPLICIT;
-static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
-static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
-static ID id_each;
-
/*
* Ruby to ASN1 converters
*/
@@ -777,6 +751,10 @@ ossl_asn1data_to_der(VALUE self)
}
}
+static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
+static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
+ int depth, int yield, long *num_read);
+
static VALUE
int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
VALUE tc, long *num_read)
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 4205d414609bf0..8a4ff481872abc 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -1674,30 +1674,7 @@ def connect
debug "opening connection to #{conn_addr}:#{conn_port}..."
begin
- s =
- case @tcpsocket_supports_open_timeout
- when nil, true
- begin
- # Use built-in timeout in TCPSocket.open if available
- sock = TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout)
- @tcpsocket_supports_open_timeout = true
- sock
- rescue ArgumentError => e
- raise if !(e.message.include?('unknown keyword: :open_timeout') || e.message.include?('wrong number of arguments (given 5, expected 2..4)'))
- @tcpsocket_supports_open_timeout = false
-
- # Fallback to Timeout.timeout if TCPSocket.open does not support open_timeout
- Timeout.timeout(@open_timeout, Net::OpenTimeout) {
- TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
- }
- end
- when false
- # The current Ruby is known to not support TCPSocket(open_timeout:).
- # Directly fall back to Timeout.timeout to avoid performance penalty incured by rescue.
- Timeout.timeout(@open_timeout, Net::OpenTimeout) {
- TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
- }
- end
+ s = timeouted_connect(conn_addr, conn_port)
rescue => e
e = Net::OpenTimeout.new(e) if e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions
raise e, "Failed to open TCP connection to " +
@@ -1795,6 +1772,29 @@ def connect
end
private :connect
+ def timeouted_connect(conn_addr, conn_port)
+ if @tcpsocket_supports_open_timeout == nil || @tcpsocket_supports_open_timeout == true
+ # Try to use built-in open_timeout in TCPSocket.open if:
+ # - The current Ruby runtime is known to support it, or
+ # - It is unknown whether the current Ruby runtime supports it (so we'll try).
+ begin
+ sock = TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout)
+ @tcpsocket_supports_open_timeout = true
+ return sock
+ rescue ArgumentError => e
+ raise if !(e.message.include?('unknown keyword: :open_timeout') || e.message.include?('wrong number of arguments (given 5, expected 2..4)'))
+ @tcpsocket_supports_open_timeout = false
+ end
+ end
+
+ # This Ruby runtime is known not to support `TCPSocket(open_timeout:)`.
+ # Directly fall back to Timeout.timeout to avoid performance penalty incured by rescue.
+ Timeout.timeout(@open_timeout, Net::OpenTimeout) {
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
+ }
+ end
+ private :timeouted_connect
+
def on_connect
end
private :on_connect
diff --git a/lib/timeout.rb b/lib/timeout.rb
index e1f0a4a78c6f59..f173d028a39d0a 100644
--- a/lib/timeout.rb
+++ b/lib/timeout.rb
@@ -133,6 +133,7 @@ def self.ensure_timeout_thread_created
end
end
end
+ private_class_method :ensure_timeout_thread_created
# We keep a private reference so that time mocking libraries won't break
# Timeout.
@@ -167,7 +168,7 @@ def self.ensure_timeout_thread_created
# Note that this is both a method of module Timeout, so you can include
# Timeout into your classes so they have a #timeout method, as well as
# a module method, so you can call it directly as Timeout.timeout().
- def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
+ def self.timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
return yield(sec) if sec == nil or sec.zero?
raise ArgumentError, "Timeout sec must be a non-negative number" if 0 > sec
@@ -177,7 +178,7 @@ def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
return scheduler.timeout_after(sec, klass || Error, message, &block)
end
- Timeout.ensure_timeout_thread_created
+ ensure_timeout_thread_created
perform = Proc.new do |exc|
request = Request.new(Thread.current, sec, exc, message)
QUEUE_MUTEX.synchronize do
@@ -197,5 +198,8 @@ def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
Error.handle_timeout(message, &perform)
end
end
- module_function :timeout
+
+ private def timeout(*args, &block)
+ Timeout.timeout(*args, &block)
+ end
end
diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb
index df8b0accb36c84..5978ecf6736e10 100644
--- a/test/openssl/test_asn1.rb
+++ b/test/openssl/test_asn1.rb
@@ -426,17 +426,28 @@ def test_utctime
OpenSSL::ASN1::UTCTime.new(Time.new(2049, 12, 31, 23, 0, 0, "-04:00")).to_der
}
- # not implemented
+ # UTC offset (BER): ASN1_TIME_to_tm() may or may not support it
# decode_test B(%w{ 17 11 }) + "500908234339+0930".b,
# OpenSSL::ASN1::UTCTime.new(Time.new(1950, 9, 8, 23, 43, 39, "+09:30"))
# decode_test B(%w{ 17 0F }) + "5009082343-0930".b,
# OpenSSL::ASN1::UTCTime.new(Time.new(1950, 9, 8, 23, 43, 0, "-09:30"))
- # assert_raise(OpenSSL::ASN1::ASN1Error) {
- # OpenSSL::ASN1.decode(B(%w{ 17 0C }) + "500908234339".b)
- # }
- # assert_raise(OpenSSL::ASN1::ASN1Error) {
- # OpenSSL::ASN1.decode(B(%w{ 17 0D }) + "500908234339Y".b)
- # }
+
+ # Seconds is omitted (BER)
+ # decode_test B(%w{ 18 0D }) + "201612081934Z".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 0))
+
+ # Fractional seconds is not allowed in UTCTime
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 17 0F }) + "160908234339.5Z".b)
+ }
+
+ # Missing "Z"
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 17 0C }) + "500908234339".b)
+ }
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 17 0D }) + "500908234339Y".b)
+ }
end
def test_generalizedtime
@@ -444,24 +455,46 @@ def test_generalizedtime
OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 29))
encode_decode_test B(%w{ 18 0F }) + "99990908234339Z".b,
OpenSSL::ASN1::GeneralizedTime.new(Time.utc(9999, 9, 8, 23, 43, 39))
- # not implemented
+
+ # Fractional seconds (DER). Not supported by ASN1_TIME_to_tm()
+ # because struct tm cannot store it.
+ # encode_decode_test B(%w{ 18 11 }) + "20161208193439.5Z".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 39.5))
+
+ # UTC offset (BER): ASN1_TIME_to_tm() may or may not support it
# decode_test B(%w{ 18 13 }) + "20161208193439+0930".b,
# OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 39, "+09:30"))
# decode_test B(%w{ 18 11 }) + "201612081934-0930".b,
# OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 0, "-09:30"))
# decode_test B(%w{ 18 11 }) + "201612081934-09".b,
# OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 0, "-09:00"))
+
+ # Minutes and seconds are omitted (BER)
+ # decode_test B(%w{ 18 0B }) + "2016120819Z".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 0, 0))
+ # Fractional hours (BER)
# decode_test B(%w{ 18 0D }) + "2016120819.5Z".b,
# OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 30, 0))
+ # Fractional hours with "," as the decimal separator (BER)
# decode_test B(%w{ 18 0D }) + "2016120819,5Z".b,
# OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 30, 0))
+
+ # Seconds is omitted (BER)
+ # decode_test B(%w{ 18 0D }) + "201612081934Z".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 0))
+ # Fractional minutes (BER)
# decode_test B(%w{ 18 0F }) + "201612081934.5Z".b,
# OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 30))
- # decode_test B(%w{ 18 11 }) + "20161208193439.5Z".b,
- # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 39.5))
- # assert_raise(OpenSSL::ASN1::ASN1Error) {
- # OpenSSL::ASN1.decode(B(%w{ 18 0D }) + "201612081934Y".b)
- # }
+
+ # Missing "Z"
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 18 0F }) + "20161208193429Y".b)
+ }
+
+ # Encoding year out of range
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1::GeneralizedTime.new(Time.utc(10000, 9, 8, 23, 43, 39)).to_der
+ }
end
def test_basic_asn1data
diff --git a/test/test_timeout.rb b/test/test_timeout.rb
index 01156867b05609..e367df757cc9b2 100644
--- a/test/test_timeout.rb
+++ b/test/test_timeout.rb
@@ -4,6 +4,12 @@
class TestTimeout < Test::Unit::TestCase
+ def test_public_methods
+ assert_equal [:timeout], Timeout.private_instance_methods(false)
+ assert_equal [], Timeout.public_instance_methods(false)
+ assert_equal [:timeout], Timeout.singleton_class.public_instance_methods(false)
+ end
+
def test_work_is_done_in_same_thread_as_caller
assert_equal Thread.current, Timeout.timeout(10){ Thread.current }
end