Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions ext/date/date_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -4515,7 +4515,8 @@ d_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
}

VALUE date__strptime(const char *str, size_t slen,
const char *fmt, size_t flen, VALUE hash);
const char *fmt, size_t flen,
VALUE hash, rb_encoding *enc);

static VALUE
date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
Expand All @@ -4524,6 +4525,7 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
VALUE vstr, vfmt, hash;
const char *str, *fmt;
size_t slen, flen;
rb_encoding *enc;

rb_scan_args(argc, argv, "11", &vstr, &vfmt);

Expand All @@ -4537,33 +4539,18 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
if (argc < 2) {
fmt = default_fmt;
flen = strlen(default_fmt);
enc = rb_enc_get(vstr);
}
else {
if (!rb_enc_str_asciicompat_p(vfmt))
rb_raise(rb_eArgError,
"format should have ASCII compatible encoding");
enc = rb_enc_check(vstr, vfmt);
fmt = RSTRING_PTR(vfmt);
flen = RSTRING_LEN(vfmt);
}
hash = rb_hash_new();
if (NIL_P(date__strptime(str, slen, fmt, flen, hash)))
return Qnil;

{
VALUE zone = ref_hash("zone");
VALUE left = ref_hash("leftover");

if (!NIL_P(zone)) {
rb_enc_copy(zone, vstr);
set_hash("zone", zone);
}
if (!NIL_P(left)) {
rb_enc_copy(left, vstr);
set_hash("leftover", left);
}
}

return hash;
return date__strptime(str, slen, fmt, flen, hash, enc);
}

/*
Expand Down
20 changes: 10 additions & 10 deletions ext/date/date_strptime.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ static const int ABBREVIATED_MONTH_NAME_LENGTH = 3;

#define f_match(r,s) rb_funcall(r, rb_intern("match"), 1, s)
#define f_aref(o,i) rb_funcall(o, rb_intern("[]"), 1, i)
#define f_end(o,i) rb_funcall(o, rb_intern("end"), 1, i)

#define issign(c) ((c) == '-' || (c) == '+')

Expand Down Expand Up @@ -144,7 +143,7 @@ valid_range_p(VALUE v, int a, int b)
do { \
size_t l; \
l = date__strptime_internal(&str[si], slen - si, \
fmt, sizeof fmt - 1, hash); \
fmt, sizeof fmt - 1, hash, enc); \
if (fail_p()) \
return 0; \
si += l; \
Expand All @@ -160,7 +159,8 @@ head_match_p(size_t len, const char *name, const char *str, size_t slen, size_t

static size_t
date__strptime_internal(const char *str, size_t slen,
const char *fmt, size_t flen, VALUE hash)
const char *fmt, size_t flen,
VALUE hash, rb_encoding *enc)
{
size_t si, fi;
int c;
Expand Down Expand Up @@ -597,15 +597,14 @@ date__strptime_internal(const char *str, size_t slen,

b = rb_backref_get();
rb_match_busy(b);
m = f_match(pat, rb_usascii_str_new(&str[si], slen - si));
m = f_match(pat, rb_enc_str_new(&str[si], slen - si, enc));

if (!NIL_P(m)) {
VALUE s, l, o;
VALUE s, o;

s = rb_reg_nth_match(1, m);
l = f_end(m, INT2FIX(0));
o = date_zone_to_diff(s);
si += NUM2LONG(l);
si += RSTRING_LEN(s);
set_hash("zone", s);
set_hash("offset", o);
rb_backref_set(b);
Expand Down Expand Up @@ -654,20 +653,21 @@ date__strptime_internal(const char *str, size_t slen,

VALUE
date__strptime(const char *str, size_t slen,
const char *fmt, size_t flen, VALUE hash)
const char *fmt, size_t flen,
VALUE hash, rb_encoding *enc)
{
size_t si;
VALUE cent, merid;

si = date__strptime_internal(str, slen, fmt, flen, hash);
si = date__strptime_internal(str, slen, fmt, flen, hash, enc);

if (fail_p())
return Qnil;

if (slen > si) {
VALUE s;

s = rb_usascii_str_new(&str[si], slen - si);
s = rb_enc_str_new(&str[si], slen - si, enc);
set_hash("leftover", s);
}

Expand Down
7 changes: 7 additions & 0 deletions test/date/test_date_strptime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -533,4 +533,11 @@ def to_str
assert_equal(6, d[:mon])
assert_equal(1, d[:mday])
end

def test_nonascii_string
nonalpha = "\u{2600 fe0f}"
s = "2011-10-05T22:26:12#{nonalpha}"

assert_nil(DateTime._strptime(s))
end
end