Ruby Issue Tracking System: Issues
https://redmine.ruby-lang.org/
https://redmine.ruby-lang.org/favicon.ico?1711330511
2022-11-16T05:15:19Z
Ruby Issue Tracking System
Redmine
Ruby master - Bug #19132 (Closed): `**` を引数に指定すると no anonymous keyword rest parameter になる
https://redmine.ruby-lang.org/issues/19132
2022-11-16T05:15:19Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>Ruby 3.2.0-preview3 で次のスクリプトを実行するとエラーになります。</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">hoge</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="ss">k: </span><span class="kp">nil</span><span class="p">,</span> <span class="o">**</span><span class="p">)</span>
<span class="n">foo</span><span class="p">(</span><span class="o">*</span><span class="p">,</span> <span class="o">**</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
<pre><code>% ruby hoge.rb
hoge.rb:2: no anonymous keyword rest parameter
</code></pre>
<p>次のようにキーワードパラメータが <code>**</code> だけであればエラーになりませんでした。</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">hoge</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="o">**</span><span class="p">)</span>
<span class="n">foo</span><span class="p">(</span><span class="o">*</span><span class="p">,</span> <span class="o">**</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
Ruby master - Bug #18433 (Closed): 「‘rb_cData’ is deprecated: by: rb_cObject. Will be removed in...
https://redmine.ruby-lang.org/issues/18433
2021-12-26T03:07:10Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>拡張ライブラリ内で rb_cData を使うと</p>
<pre><code>‘rb_cData’ is deprecated: by: rb_cObject. Will be removed in 3.1.
</code></pre>
<p>という warning が出力されますが、これが 3.1 でも出ます。<br>
別に害はないのですが、メッセージとしては妙な感じです。</p>
<pre><code>/tmp/hoge% cat hoge.c
#include <ruby.h>
void Init_hoge(void)
{
rb_cData;
}
/tmp/hoge% cat extconf.rb
require 'mkmf'
create_makefile('hoge')
/tmp/hoge% ruby -v extconf.rb
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-linux]
creating Makefile
/tmp/hoge% make
compiling hoge.c
hoge.c: In function ‘Init_hoge’:
hoge.c:4:3: warning: ‘rb_cData’ is deprecated: by: rb_cObject. Will be removed in 3.1. [-Wdeprecated-declarations]
4 | rb_cData;
| ^~~~~~~~
In file included from /home/tommy/ruby31/include/ruby-3.1.0/ruby/internal/core.h:27,
from /home/tommy/ruby31/include/ruby-3.1.0/ruby/ruby.h:28,
from /home/tommy/ruby31/include/ruby-3.1.0/ruby.h:38,
from hoge.c:1:
/home/tommy/ruby31/include/ruby-3.1.0/ruby/internal/core/rdata.h:382:1: note: declared here
382 | rb_cData(void)
| ^~~~~~~~
hoge.c: At top level:
cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics
linking shared-object hoge.so
/tmp/hoge%
</code></pre>
Ruby master - Bug #15426 (Closed): BigDecimal: "1.2.3".to_d が 0.0 になる
https://redmine.ruby-lang.org/issues/15426
2018-12-17T15:54:00Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>Ruby 2.6.0-rc2 で "1.2.3".to_d が 0.0 になります。</p>
<pre><code>% ruby -v -rbigdecimal -rbigdecimal/util -e 'p "1.2.3".to_d'
ruby 2.6.0rc2 (2018-12-15 trunk 66408) [x86_64-linux]
0.0
</code></pre>
<p>Ruby 2.5.3p105 では 0.12e1 を返してました。</p>
<pre><code>% ruby -v -rbigdecimal -rbigdecimal/util -e 'p "1.2.3".to_d'
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
0.12e1
</code></pre>
<p>NEWS の</p>
<pre><code>* String#to_d parses the receiver string like String#to_f.
</code></pre>
<p>この記述がそうなのかと思ったのですが、"1.2.3".to_f は 1.2 を返すのでなんか違うような気もします。</p>
Ruby master - Bug #14388 (Closed): 不正エンコーディング文字列から切り出した正当なエンコーディング文字列が invalid encoding になる
https://redmine.ruby-lang.org/issues/14388
2018-01-24T08:14:36Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">data</span> <span class="o">=</span> <span class="s2">"</span><span class="se">\xFF</span><span class="s2">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"</span>
<span class="nb">p</span> <span class="n">data</span><span class="p">.</span><span class="nf">encoding</span> <span class="c1">#=> #<Encoding:UTF-8></span>
<span class="nb">p</span> <span class="n">data</span> <span class="c1">#=> "\xFFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"</span>
<span class="nb">p</span> <span class="n">data</span><span class="p">.</span><span class="nf">valid_encoding?</span> <span class="c1">#=> false</span>
<span class="n">data2</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="o">..-</span><span class="mi">1</span><span class="p">]</span>
<span class="nb">p</span> <span class="n">data2</span> <span class="c1">#=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"</span>
<span class="nb">p</span> <span class="n">data2</span><span class="p">.</span><span class="nf">valid_encoding?</span> <span class="c1">#=> false</span>
<span class="n">data3</span> <span class="o">=</span> <span class="n">data2</span> <span class="o">+</span> <span class="s2">""</span>
<span class="nb">p</span> <span class="n">data3</span><span class="p">.</span><span class="nf">valid_encoding?</span> <span class="c1">#=> true</span>
</code></pre>
<p>data は invalid ですが、data から切り出した data2 は valid のはずです。<br>
末尾に空文字列を追加すると valid になります。</p>
Ruby master - Bug #13995 (Closed): Process.initgroups がNUL終端文字列を期待している
https://redmine.ruby-lang.org/issues/13995
2017-10-10T15:26:19Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>Process.initgroups がNUL終端文字列を期待していて、SHARABLE_MIDDLE_SUBSTRING=1 時におかしくなります。<br>
こんなに長いユーザー名は実際には使われないと思うので実害はないかもしれません。</p>
<pre><code># grep abcdefg /etc/group
test:x:999:abcdefghijklmnopqrstuvwxyz
# ruby -e 'p Process.initgroups("abcdefghijklmnopqrstuvwxyz!".chop, 123)'
[123]
</code></pre>
<p>パッチ適用後は正しく動きます。</p>
<pre><code># ruby -e 'p Process.initgroups("abcdefghijklmnopqrstuvwxyz!".chop, 123)'
[123, 999]
</code></pre>
<p>パッチ:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/process.c b/process.c
index 2d842176bd..97ba885fca 100644
</span><span class="gd">--- a/process.c
</span><span class="gi">+++ b/process.c
</span><span class="p">@@ -5948,7 +5948,7 @@</span> proc_setgroups(VALUE obj, VALUE ary)
static VALUE
proc_initgroups(VALUE obj, VALUE uname, VALUE base_grp)
{
<span class="gd">- if (initgroups(StringValuePtr(uname), OBJ2GID(base_grp)) != 0) {
</span><span class="gi">+ if (initgroups(StringValueCStr(uname), OBJ2GID(base_grp)) != 0) {
</span> rb_sys_fail(0);
}
return proc_getgroups(obj);
</code></pre>
Ruby master - Bug #13994 (Closed): Socket.getnameinfo が NUL終端文字列を期待している
https://redmine.ruby-lang.org/issues/13994
2017-10-10T15:06:22Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>Socket.getnameinfo が NUL終端文字列を期待していて、SHARABLE_MIDDLE_SUBSTRING=1 時におかしくなります。</p>
<pre><code>% grep abcdefg /etc/hosts /etc/services
/etc/hosts:192.168.0.99 abcdefghijklmnopqrstuvwxyz.test
/etc/services:abcdefghijklmnopqrstuvwxyz 9999/tcp
% ruby -rsocket -e 'p Socket.getnameinfo(["AF_INET", "abcdefghijklmnopqrstuvwxyz!".chop, "abcdefghijklmnopqrstuvwxyz.test!".chop])'
Traceback (most recent call last):
1: from -e:1:in `<main>'
-e:1:in `getnameinfo': getaddrinfo: Servname not supported for ai_socktype (SocketError)
</code></pre>
<p>パッチ適用後は次のようになります。</p>
<pre><code>% ruby -rsocket -e 'p Socket.getnameinfo(["AF_INET", "abcdefghijklmnopqrstuvwxyz!".chop, "abcdefghijklmnopqrstuvwxyz.test!".chop])'
["abcdefghijklmnopqrstuvwxyz.test", "abcdefghijklmnopqrstuvwxyz"]
</code></pre>
<p>パッチ:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 14e069bb8d..9eb36def14 100644
</span><span class="gd">--- a/ext/socket/socket.c
</span><span class="gi">+++ b/ext/socket/socket.c
</span><span class="p">@@ -1287,7 +1287,7 @@</span> sock_s_getnameinfo(int argc, VALUE *argv)
hptr = NULL;
}
else {
<span class="gd">- strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));
</span><span class="gi">+ strncpy(hbuf, StringValueCStr(host), sizeof(hbuf));
</span> hbuf[sizeof(hbuf) - 1] = '\0';
hptr = hbuf;
}
<span class="p">@@ -1301,7 +1301,7 @@</span> sock_s_getnameinfo(int argc, VALUE *argv)
pptr = pbuf;
}
else {
<span class="gd">- strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));
</span><span class="gi">+ strncpy(pbuf, StringValueCStr(port), sizeof(pbuf));
</span> pbuf[sizeof(pbuf) - 1] = '\0';
pptr = pbuf;
}
</code></pre>
Ruby master - Bug #13993 (Closed): Psych::Emitter が NUL終端文字列を期待している
https://redmine.ruby-lang.org/issues/13993
2017-10-10T14:42:32Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>Psych::Emitter が NUL終端文字列を期待していて、SHARABLE_MIDDLE_SUBSTRING=1 時におかしくなります。</p>
<p>次のプログラム(Psychに詳しくないので変なコードかもしれません)を実行すると、</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'psych'</span>
<span class="nb">require</span> <span class="s1">'stringio'</span>
<span class="n">output</span> <span class="o">=</span> <span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span>
<span class="n">emitter</span> <span class="o">=</span> <span class="no">Psych</span><span class="o">::</span><span class="no">Emitter</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="n">s</span> <span class="o">=</span> <span class="s2">"a"</span><span class="o">*</span><span class="mi">100</span>
<span class="n">emitter</span><span class="p">.</span><span class="nf">start_stream</span><span class="p">(</span><span class="no">Psych</span><span class="o">::</span><span class="no">Parser</span><span class="o">::</span><span class="no">UTF8</span><span class="p">)</span>
<span class="n">emitter</span><span class="p">.</span><span class="nf">start_document</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="p">[],</span> <span class="kp">false</span><span class="p">)</span>
<span class="n">emitter</span><span class="p">.</span><span class="nf">scalar</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">30</span><span class="p">],</span> <span class="kp">nil</span><span class="p">,</span> <span class="kp">true</span><span class="p">,</span> <span class="kp">false</span><span class="p">,</span> <span class="no">Psych</span><span class="o">::</span><span class="no">Nodes</span><span class="o">::</span><span class="no">Scalar</span><span class="o">::</span><span class="no">PLAIN</span><span class="p">)</span>
<span class="n">emitter</span><span class="p">.</span><span class="nf">end_document</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
<span class="n">emitter</span><span class="p">.</span><span class="nf">end_stream</span>
<span class="nb">puts</span> <span class="n">output</span><span class="p">.</span><span class="nf">string</span>
</code></pre>
<p>結果が次のようになります。</p>
<pre><code>%YAML 1.1
--- &aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa x
...
</code></pre>
<p>パッチ適用後は次のようになります。</p>
<pre><code>%YAML 1.1
--- &aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa x
...
</code></pre>
<p>パッチ:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/ext/psych/psych_emitter.c b/ext/psych/psych_emitter.c
index bb4c4b226b..55bd417004 100644
</span><span class="gd">--- a/ext/psych/psych_emitter.c
</span><span class="gi">+++ b/ext/psych/psych_emitter.c
</span><span class="p">@@ -272,8 +272,8 @@</span> static VALUE scalar(
yaml_scalar_event_initialize(
&event,
<span class="gd">- (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)),
- (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)),
</span><span class="gi">+ (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
+ (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
</span> (yaml_char_t*)StringValuePtr(value),
(int)RSTRING_LEN(value),
plain ? 1 : 0,
<span class="p">@@ -319,8 +319,8 @@</span> static VALUE start_sequence(
yaml_sequence_start_event_initialize(
&event,
<span class="gd">- (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)),
- (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)),
</span><span class="gi">+ (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
+ (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
</span> implicit ? 1 : 0,
(yaml_sequence_style_t)NUM2INT(style)
);
<span class="p">@@ -383,8 +383,8 @@</span> static VALUE start_mapping(
yaml_mapping_start_event_initialize(
&event,
<span class="gd">- (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor)),
- (yaml_char_t *)(NIL_P(tag) ? NULL : StringValuePtr(tag)),
</span><span class="gi">+ (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
+ (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
</span> implicit ? 1 : 0,
(yaml_mapping_style_t)NUM2INT(style)
);
<span class="p">@@ -432,7 +432,7 @@</span> static VALUE alias(VALUE self, VALUE anchor)
yaml_alias_event_initialize(
&event,
<span class="gd">- (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValuePtr(anchor))
</span><span class="gi">+ (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor))
</span> );
emit(emitter, &event);
<span class="gh">diff --git a/ext/psych/psych_yaml_tree.c b/ext/psych/psych_yaml_tree.c
index bcf24d2070..7aca9114c9 100644
</span><span class="gd">--- a/ext/psych/psych_yaml_tree.c
</span><span class="gi">+++ b/ext/psych/psych_yaml_tree.c
</span><span class="p">@@ -9,7 +9,7 @@</span> VALUE cPsychVisitorsYamlTree;
*/
static VALUE private_iv_get(VALUE self, VALUE target, VALUE prop)
{
<span class="gd">- return rb_attr_get(target, rb_intern(StringValuePtr(prop)));
</span><span class="gi">+ return rb_attr_get(target, rb_intern(StringValueCStr(prop)));
</span> }
void Init_psych_yaml_tree(void)
</code></pre>
Ruby master - Bug #13961 (Closed): String#unpack の warning メッセージが SHARABLE_MIDDLE_SUBSTRING=1 を考慮...
https://redmine.ruby-lang.org/issues/13961
2017-10-01T15:01:09Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>String#unpack で不正なディレクティブが指定された時のwarningメッセージが指定文字列ではなくNUL終端まで出力してしまいます。</p>
<pre><code>% ruby -we '"hoge".unpack(("o"*100)[0,24])'
-e:1: warning: unknown unpack directive 'o' in 'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo'
-e:1: warning: unknown unpack directive 'o' in 'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo'
</code></pre>
<p>次のパッチで直ると思います。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/pack.c b/pack.c
index 327c478af8..532e03cb14 100644
</span><span class="gd">--- a/pack.c
</span><span class="gi">+++ b/pack.c
</span><span class="p">@@ -1738,8 +1738,8 @@</span> pack_unpack_internal(VALUE str, VALUE fmt, int mode)
break;
default:
<span class="gd">- rb_warning("unknown unpack directive '%c' in '%s'",
- type, RSTRING_PTR(fmt));
</span><span class="gi">+ rb_warning("unknown unpack directive '%c' in '% "PRIsVALUE"'",
+ type, fmt);
</span> break;
}
}
</code></pre>
Ruby master - Bug #13960 (Closed): ARGF.inplace_mode= が SHARABLE_MIDDLE_SUBSTRING=1 を考慮していない
https://redmine.ruby-lang.org/issues/13960
2017-10-01T14:24:51Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>SHARABLE_MIDDLE_SUBSTRING=1 でコンパイルしたRubyで、ARGF.inplace_mode= がNUL終端まで文字列を使用してしまいます。</p>
<pre><code>% echo hoge > hoge
% ruby -e 'ARGF.inplace_mode=(".abcdefghijklmnopqrstuvwxyz"*2)[0,27]; ARGF.each_line{|line| print line.sub("hoge","fuga")}' hoge
% ls hoge*
hoge hoge.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz
</code></pre>
<p>次のパッチで直ると思います。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/io.c b/io.c
index 1254e92363..ed4a562d8b 100644
</span><span class="gd">--- a/io.c
</span><span class="gi">+++ b/io.c
</span><span class="p">@@ -12224,7 +12224,7 @@</span> argf_inplace_mode_set(VALUE argf, VALUE val)
ARGF.inplace = 0;
}
else {
<span class="gd">- StringValue(val);
</span><span class="gi">+ StringValueCStr(val);
</span> if (ARGF.inplace) free(ARGF.inplace);
ARGF.inplace = 0;
ARGF.inplace = strdup(RSTRING_PTR(val));
</code></pre>
Ruby master - Bug #13957 (Closed): readline が SHARABLE_MIDDLE_SUBSTRING=1 を考慮していない
https://redmine.ruby-lang.org/issues/13957
2017-09-30T14:33:19Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>SHARABLE_MIDDLE_SUBSTRING=1 でコンパイルしたRubyで、Readline.insert_text の文字列が正しく扱われません。</p>
<pre><code>% ruby -rreadline -e 'p Readline.insert_text(("a"*100)[0,24]).line_buffer'
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
</code></pre>
<p>次のパッチで直ると思います。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/ext/readline/readline.c b/ext/readline/readline.c
index 253798f9e6..deebc282f5 100644
</span><span class="gd">--- a/ext/readline/readline.c
</span><span class="gi">+++ b/ext/readline/readline.c
</span><span class="p">@@ -93,6 +93,7 @@</span> static char **readline_attempted_completion_function(const char *text,
#define OutputStringValue(str) do {\
SafeStringValue(str);\
<span class="gi">+ StringValueCStr(str);\
</span> (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
} while (0)\
</code></pre>
<p>パッチ適用後</p>
<pre><code>% ruby -rreadline -e 'p Readline.insert_text(("a"*100)[0,24]).line_buffer'
"aaaaaaaaaaaaaaaaaaaaaaaa"
</code></pre>
Ruby master - Bug #13955 (Closed): NKF.nkf のオプション文字列が SHARABLE_MIDDLE_SUBSTRING=1 を考慮していない
https://redmine.ruby-lang.org/issues/13955
2017-09-30T08:01:26Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>SHARABLE_MIDDLE_SUBSTRING=1 でコンパイルしたRubyで、NKF.nkf のオプション文字列が正しく扱われません。</p>
<pre><code>% ruby -rnkf -e 'opt="--ic=UTF-8 --oc=EUC-JISX0213 -w"[0,28]; p opt; p NKF.nkf(opt, "あ").encoding'
"--ic=UTF-8 --oc=EUC-JISX0213"
#<Encoding:UTF-8>
</code></pre>
<p>次のパッチで直ると思います。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/ext/nkf/nkf.c b/ext/nkf/nkf.c
index 9613a925ce..df32e9cf0b 100644
</span><span class="gd">--- a/ext/nkf/nkf.c
</span><span class="gi">+++ b/ext/nkf/nkf.c
</span><span class="p">@@ -137,7 +137,7 @@</span> rb_nkf_convert(VALUE obj, VALUE opt, VALUE src)
{
VALUE tmp;
reinit();
<span class="gd">- StringValue(opt);
</span><span class="gi">+ StringValueCStr(opt);
</span> nkf_split_options(RSTRING_PTR(opt));
if (!output_encoding) rb_raise(rb_eArgError, "no output encoding given");
</code></pre>
<p>適用後</p>
<pre><code>% ruby -rnkf -e 'opt="--ic=UTF-8 --oc=EUC-JISX0213 -w"[0,28]; p opt; p NKF.nkf(opt, "あ").encoding'
"--ic=UTF-8 --oc=EUC-JISX0213"
#<Encoding:EUC-JIS-2004>
</code></pre>
Ruby master - Bug #13954 (Closed): Etc.getpwnam, getgrnam が SHARABLE_MIDDLE_SUBSTRING=1 を考慮していない
https://redmine.ruby-lang.org/issues/13954
2017-09-30T07:23:57Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>SHARABLE_MIDDLE_SUBSTRING=1 でコンパイルしたRubyで Etc.getpwnam, getgrnam が共有元の文字列終端まで使用してしまいます。</p>
<pre><code>% sudo useradd abcdefghijklmnopqrstuvwxyz
% ruby -retc -e 'p Etc.getpwnam("abcdefghijklmnopqrstuvwxyz")'
#<struct Etc::Passwd name="abcdefghijklmnopqrstuvwxyz", passwd="x", uid=1002, gid=1002, gecos="", dir="/home/abcdefghijklmnopqrstuvwxyz", shell="">
% ruby -retc -e 'p Etc.getpwnam(("abcdefghijklmnopqrstuvwxyz"*10)[0,26])'
Traceback (most recent call last):
1: from -e:1:in `<main>'
-e:1:in `getpwnam': can't find user for abcdefghijklmnopqrstuvwxyz (ArgumentError)
</code></pre>
<p>次のパッチで直ると思います。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index 5d964ba518..66fd26f436 100644
</span><span class="gd">--- a/ext/etc/etc.c
</span><span class="gi">+++ b/ext/etc/etc.c
</span><span class="p">@@ -217,6 +217,7 @@</span> etc_getpwnam(VALUE obj, VALUE nam)
struct passwd *pwd;
SafeStringValue(nam);
<span class="gi">+ StringValueCStr(nam);
</span> pwd = getpwnam(RSTRING_PTR(nam));
if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, nam);
return setup_passwd(pwd);
<span class="p">@@ -460,6 +461,7 @@</span> etc_getgrnam(VALUE obj, VALUE nam)
struct group *grp;
SafeStringValue(nam);
<span class="gi">+ StringValueCStr(nam);
</span> grp = getgrnam(RSTRING_PTR(nam));
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, nam);
return setup_group(grp);
</code></pre>
Ruby master - Bug #13953 (Closed): gdbm が SHARABLE_MIDDLE_SUBSTRING=1 を考慮していない
https://redmine.ruby-lang.org/issues/13953
2017-09-30T04:37:26Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>SHARABLE_MIDDLE_SUBSTRING=1 でコンパイルしたRubyで、GDBM.new が指定した文字列ではなく共有元の文字列終端までファイル名として使用してしまいます。</p>
<pre><code>% ruby -rgdbm -e 'GDBM.new(("0123456789"*10)[0,24])'
% ls
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
</code></pre>
<p>次のパッチで直ると思います。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/ext/gdbm/gdbm.c b/ext/gdbm/gdbm.c
index 709f466cd8..cbf96c29f9 100644
</span><span class="gd">--- a/ext/gdbm/gdbm.c
</span><span class="gi">+++ b/ext/gdbm/gdbm.c
</span><span class="p">@@ -228,7 +228,7 @@</span> fgdbm_initialize(int argc, VALUE *argv, VALUE obj)
if (!NIL_P(vflags))
flags = NUM2INT(vflags);
<span class="gd">- SafeStringValue(file);
</span><span class="gi">+ FilePathValue(file);
</span>
#ifdef GDBM_CLOEXEC
/* GDBM_CLOEXEC is available since gdbm 1.10. */
</code></pre>
Ruby master - Bug #12726 (Closed): OpenSSL::PKCS12.new がプライベートキーを含まないデータでエラーになる
https://redmine.ruby-lang.org/issues/12726
2016-09-05T06:45:04Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>次のように作成したプライベートキーを含まない pfx ファイルを、</p>
<pre><code>% openssl pkcs12 -export -out hoge.pfx -in hoge.pem -nokeys
Enter Export Password:hoge
Verifying - Enter Export Password:hoge
</code></pre>
<p>OpenSSL::PKCS12.new で読み込むとエラーになります。</p>
<pre><code>% ruby -ropenssl -e 'OpenSSL::PKCS12.new(File.read("hoge.pfx"), "hoge")'
-e:1:in `initialize': Cannot make new key from NULL. (OpenSSL::PKey::PKeyError)
from -e:1:in `new'
from -e:1:in `<main>'
</code></pre>
<p>Ruby 2.1, 2.2, 2.3 でも同様でした。</p>
<p>次のパッチで直ります。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gd">--- a/ext/openssl/ossl_pkcs12.c
</span><span class="gi">+++ b/ext/openssl/ossl_pkcs12.c
</span><span class="p">@@ -190,9 +190,11 @@</span> ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
ossl_raise(ePKCS12Error, "PKCS12_parse");
ERR_pop_to_mark();
<span class="gd">- pkey = rb_protect((VALUE (*)(VALUE))ossl_pkey_new, (VALUE)key,
- &st); /* NO DUP */
- if(st) goto err;
</span><span class="gi">+ if (key) {
+ pkey = rb_protect((VALUE (*)(VALUE))ossl_pkey_new, (VALUE)key,
+ &st); /* NO DUP */
+ if(st) goto err;
+ }
</span> cert = rb_protect((VALUE (*)(VALUE))ossl_x509_new, (VALUE)x509, &st);
if(st) goto err;
if(x509s){
</code></pre>
Ruby master - Bug #12087 (Closed): Find.find に存在しないパスを渡した時のエラーにパス名がない
https://redmine.ruby-lang.org/issues/12087
2016-02-19T09:08:39Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p><code>ruby -rfind -e 'Find.find("/hoge"){}'</code> で /hoge が存在しない場合に発生するエラーが <code>No such file or directory (Errno::ENOENT)</code> でパス名が含まれてません。</p>
<p>エラーにパス名を含めて欲しいです。次の修正で <code>No such file or directory - /hoge (Errno::ENOENT)</code> となります。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/lib/find.rb b/lib/find.rb
index aa7a3c0..093f855 100644
</span><span class="gd">--- a/lib/find.rb
</span><span class="gi">+++ b/lib/find.rb
</span><span class="p">@@ -41,5 +41,5 @@</span> def find(*paths, ignore_error: true) # :yield: path
fs_encoding = Encoding.find("filesystem")
<span class="gd">- paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}.each do |path|
</span><span class="gi">+ paths.collect!{|d| raise Errno::ENOENT, d unless File.exist?(d); d.dup}.each do |path|
</span> path = path.to_path if path.respond_to? :to_path
enc = path.encoding == Encoding::US_ASCII ? fs_encoding : path.encoding
</code></pre>
Ruby master - Bug #11441 (Closed): Ruby 2.1 で TCPServer.new(port) がエラーになる場合 TypeError になる
https://redmine.ruby-lang.org/issues/11441
2015-08-13T13:17:51Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p><code>TCPServer.new(port)</code> がエラーになる場合、Ruby 2.1 だけ TypeError になってしまいます。</p>
<pre><code>% ruby -v -rsocket -e 'TCPServer.new(123)'
ruby 2.1.6p336 (2015-04-13 revision 50298) [x86_64-linux]
-e:1:in `initialize': no implicit conversion of nil into String (TypeError)
from -e:1:in `new'
from -e:1:in `<main>'
</code></pre>
<p>Ruby 2.0.0, 2.2 ではちゃんと適切なエラーになります。</p>
<pre><code>% ruby -v -rsocket -e 'TCPServer.new(123)'
ruby 2.0.0p576 (2014-09-19 revision 47628) [x86_64-linux]
-e:1:in `initialize': Permission denied - bind(2) (Errno::EACCES)
from -e:1:in `new'
from -e:1:in `<main>'
% ruby -v -rsocket -e 'TCPServer.new(123)'
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
-e:1:in `initialize': Permission denied - bind(2) for nil port 123 (Errno::EACCES)
from -e:1:in `new'
from -e:1:in `<main>'
</code></pre>
Ruby master - Bug #11381 (Closed): String のサブクラスをハッシュのキーに指定した時に hash メソッドが呼ばれない
https://redmine.ruby-lang.org/issues/11381
2015-07-21T14:23:57Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>String のサブクラスとして大文字小文字を同一視するようなクラスを作ろうとしましたが、<br>
そのオブジェクトをハッシュのキーに指定しても期待通りに動作しませんでした。<br>
どうやら hash メソッドが呼ばれていないようです。</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">CIString</span> <span class="o"><</span> <span class="no">String</span>
<span class="k">def</span> <span class="nf">eql?</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="nb">self</span><span class="p">.</span><span class="nf">casecmp</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">hash</span>
<span class="nb">self</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">downcase</span><span class="p">.</span><span class="nf">hash</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">h</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">k1</span> <span class="o">=</span> <span class="no">CIString</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"hoge"</span><span class="p">)</span>
<span class="n">k2</span> <span class="o">=</span> <span class="no">CIString</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"HOGE"</span><span class="p">)</span>
<span class="nb">p</span> <span class="n">k1</span><span class="p">.</span><span class="nf">eql?</span> <span class="n">k2</span> <span class="c1">#=> true</span>
<span class="nb">p</span> <span class="n">k1</span><span class="p">.</span><span class="nf">hash</span> <span class="o">==</span> <span class="n">k2</span><span class="p">.</span><span class="nf">hash</span> <span class="c1">#=> true</span>
<span class="n">h</span><span class="p">[</span><span class="n">k1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">h</span><span class="p">[</span><span class="n">k2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">2</span>
<span class="nb">p</span> <span class="n">h</span> <span class="c1">#=> {"hoge"=>1, "HOGE"=>2}</span>
</code></pre>
<p>ちなみに eql? の方はちゃんと呼ばれるようで、次のようにすると同じ値であっても別のキーとみなされます。</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">CIString</span> <span class="o"><</span> <span class="no">String</span>
<span class="k">def</span> <span class="nf">eql?</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="kp">false</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">h</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">k1</span> <span class="o">=</span> <span class="no">CIString</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"hoge"</span><span class="p">)</span>
<span class="n">k2</span> <span class="o">=</span> <span class="no">CIString</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"hoge"</span><span class="p">)</span>
<span class="n">h</span><span class="p">[</span><span class="n">k1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">h</span><span class="p">[</span><span class="n">k2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">2</span>
<span class="nb">p</span> <span class="n">h</span> <span class="c1">#=> {"hoge"=>1, "hoge"=>2}</span>
</code></pre>
<p>次のパッチで期待通りにサブクラスの hash メソッドが呼びだされました。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/hash.c b/hash.c
index 7b8733f..26e5a3d 100644
</span><span class="gd">--- a/hash.c
</span><span class="gi">+++ b/hash.c
</span><span class="p">@@ -145,7 +145,7 @@</span> rb_any_hash(VALUE a)
}
hnum = rb_objid_hash((st_index_t)a);
}
<span class="gd">- else if (BUILTIN_TYPE(a) == T_STRING) {
</span><span class="gi">+ else if (BUILTIN_TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString) {
</span> hnum = rb_str_hash(a);
}
else if (BUILTIN_TYPE(a) == T_SYMBOL) {
</code></pre>
Ruby master - Bug #11344 (Closed): Thread.handle_interrupt(TimeoutError => :never) が効かない
https://redmine.ruby-lang.org/issues/11344
2015-07-10T10:32:47Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>るりま <a href="http://docs.ruby-lang.org/ja/2.2.0/method/Thread/s/handle_interrupt.html" class="external">http://docs.ruby-lang.org/ja/2.2.0/method/Thread/s/handle_interrupt.html</a> によると、<code>Thread.handle_interrupt(TimeoutError => :never)</code> で <code>TimeoutError</code> を制御できると書かれていますが、働きません。</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'timeout'</span>
<span class="no">Thread</span><span class="p">.</span><span class="nf">handle_interrupt</span><span class="p">(</span><span class="no">TimeoutError</span> <span class="o">=></span> <span class="ss">:never</span><span class="p">)</span> <span class="k">do</span>
<span class="n">timeout</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span>
<span class="nb">sleep</span> <span class="mi">2</span>
<span class="nb">p</span> <span class="s1">'done'</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1">#=> sample.rb:4:in `sleep': execution expired (Timeout::Error)</span>
</code></pre>
<p><code>TimeoutError</code> の代わりに <code>Timeout::ExitException</code> を指定すれば働きます。</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'timeout'</span>
<span class="no">Thread</span><span class="p">.</span><span class="nf">handle_interrupt</span><span class="p">(</span><span class="no">Timeout</span><span class="o">::</span><span class="no">ExitException</span> <span class="o">=></span> <span class="ss">:never</span><span class="p">)</span> <span class="k">do</span>
<span class="n">timeout</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span>
<span class="nb">sleep</span> <span class="mi">2</span>
<span class="nb">p</span> <span class="s1">'done'</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1">#=> "done"</span>
<span class="c1">#=> sample.rb:2:in `handle_interrupt': execution expired (Timeout::ExitException)</span>
</code></pre>
<p>これは意図された挙動でしょうか。</p>
<p>なお、るりまだけじゃなく、thread.c 中のコメントにも同様の記述があります。</p>
Ruby master - Bug #11051 (Closed): Addrinfo#marshal_load がメモリーリーク
https://redmine.ruby-lang.org/issues/11051
2015-04-08T17:03:21Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p><code>Addrinfo#marshal_load</code> がメモリーリークしているように思います。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index e13684a..d838898 100644
</span><span class="gd">--- a/ext/socket/raddrinfo.c
</span><span class="gi">+++ b/ext/socket/raddrinfo.c
</span><span class="p">@@ -1643,6 +1643,7 @@</span> addrinfo_mload(VALUE self, VALUE ary)
len = res->ai->ai_addrlen;
memcpy(&ss, res->ai->ai_addr, res->ai->ai_addrlen);
<span class="gi">+ rb_freeaddrinfo(res);
</span> break;
}
}
</code></pre>
Ruby master - Feature #9981 (Closed): Net::SMTP#send_message が大量の write(2) を発行する
https://redmine.ruby-lang.org/issues/9981
2014-06-26T13:44:07Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p><code>Net::SMTP#send_message</code> でメールを送信すると1行毎に write(2) が発行されます。<br>
1MB のバイナリデータを添付すると、18000回以上 write することになります。</p>
<p>1048576(byte) * 4/3 (Base64化) / 76 (1行あたりの長さ) = 18396 行</p>
<p>SMTP の DATA 命令後はひたすらデータを送り続ければいいだけなので行ごとに write するよりもバッファリングした方がいいと思います。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb
index 5fd4f8e..64e536a 100644
</span><span class="gd">--- a/lib/net/smtp.rb
</span><span class="gi">+++ b/lib/net/smtp.rb
</span><span class="p">@@ -901,10 +901,17 @@</span> module Net
end
res = critical {
check_continue get_response('DATA')
<span class="gd">- if msgstr
- @socket.write_message msgstr
- else
- @socket.write_message_by_block(&block)
</span><span class="gi">+ socket_sync_bak = @socket.io.sync
+ begin
+ @socket.io.sync = false
+ if msgstr
+ @socket.write_message msgstr
+ else
+ @socket.write_message_by_block(&block)
+ end
+ ensure
+ @socket.io.flush
+ @socket.io.sync = socket_sync_bak
</span> end
recv_response()
}
</code></pre>
<p>これで write(2) が 350回程度になりました。</p>
Ruby master - Bug #8979 (Closed): gem のプロキシ認証情報に @ を含むとエラー
https://redmine.ruby-lang.org/issues/8979
2013-10-03T00:56:40Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>gem 実行時に認証が必要なプロキシを通す場合、プロキシの認証IDまたはパスワードに「@」を含んでいるとエラーになってしまいます。</p>
<hr>
<p>% http_proxy=<a href="http://localhost:8080" class="external">http://localhost:8080</a> http_proxy_user='foo@bar' http_proxy_pass='xxx' gem list -r mysql</p>
<p>*** REMOTE GEMS ***</p>
<h2>ERROR: While executing gem ... (URI::InvalidComponentError)<br>
bad component(expected userinfo component or user component): foo@bar</h2>
<p>また、%エンコーディングされる文字を含んでいる場合は、デコードしないで認証を試みるので、認証が失敗してしまいます。</p>
<p>添付のパッチで直ると思います。</p>
Backport193 - Backport #7658 (Closed): Rabbit が Ruby 1.9.3p362 で落ちる
https://redmine.ruby-lang.org/issues/7658
2013-01-06T10:20:02Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>Ubuntu 12.10 で Rabbit <a href="http://rabbit-shocker.org/" class="external">http://rabbit-shocker.org/</a> が Ruby 1.9.3p362 で落ちます。<br>
表紙は表示されるのですが、ページを送っていると落ちます。<br>
Rabbit の問題の可能性もあるのですが、Ruby 1.9.3p327 ではちゃんと動作していたので、Ruby の問題かと思って、このMLに投稿してます。<br>
もしかしたら OS まわりの環境の問題かもしれません。</p>
<p>Git で ruby_1_9_3 のブランチを追いかけてみると、commit 19015605 で落ちるようになったようです(Subversion の r38314)。</p>
<p>再現方法: ($HOME/ruby193 に Ruby をインストールしてあります)</p>
<p>% ~/ruby193/bin/gem install rabbit<br>
% cd ~/ruby193/lib/ruby/gems/1.9.1/gems/rabbit-2.0.6/sample<br>
% ~/ruby193/bin/rabbit rabbit.rd<br>
Rabbit のウィンドウが表示されたらスペースキーでページを進める</p>
<p>落ちたときのエラーはこんな感じで、スタックトレース等は出力されません。</p>
<pre><code> zsh: segmentation fault ~/ruby193/bin/rabbit rabbit.rd
</code></pre>
<p>--<br>
とみたまさひろ <a href="mailto:tommy@tmtm.org" class="email">tommy@tmtm.org</a><br>
<a href="http://twitter.com/tmtms" class="external">http://twitter.com/tmtms</a><br>
D68F 8F55 7F6C 5908 88EB 1EBA 25ED DEE7 BBE8 1752</p>
Backport193 - Backport #7637 (Closed): make clean で clean-static のエラー
https://redmine.ruby-lang.org/issues/7637
2012-12-30T07:24:54Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>Ruby 1.9.3 p362 で make した後に make clean すると、いくつかの ext ディレクトリで次のエラーが出ます。</p>
<pre><code> make[1]: *** `clean' に必要なターゲット `clean-static' を make するルールがありません. 中止.
</code></pre>
<p>r38528 で Makefile の clean の依存関係に clean-static が増えたのに、clean-static ターゲットがないためです。</p>
<p>trunk では r36045 で修正されているので、1.9.3 にバックポートした方が良いと思います。</p>
<p>あまり実害はないのですが一応報告しておきます。</p>
<p>--<br>
とみたまさひろ <a href="mailto:tommy@tmtm.org" class="email">tommy@tmtm.org</a><br>
<a href="http://twitter.com/tmtms" class="external">http://twitter.com/tmtms</a><br>
D68F 8F55 7F6C 5908 88EB 1EBA 25ED DEE7 BBE8 1752</p>
Ruby master - Bug #7005 (Closed): NKF: CP50221 から CP932 に変換できない文字がある
https://redmine.ruby-lang.org/issues/7005
2012-09-11T23:05:39Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>NKF で CP50221 から CP932 に変換できない文字があります。<br>
CP932 で 0xF040 から 0xF9FC までの文字のうち 589 文字が変換できません。<br>
どうやら CP50221 で1バイト目が 0x80 以上で2バイト目が 0x21-0x3F の文字が変換できないようです。</p>
<p>以下のプログラムは CP932 で 0xF040 から 0xF9FC までの文字を CP50221 に変換して CP932 に戻して、<br>
空文字列になってしまうものを出力してます。</p>
<p>Ruby 1.8.7 では変換できない文字はありませんでした。</p>
<p>require 'nkf'<br>
(0xf0..0xf9).each do |c1|<br>
(0x40..0xfc).each do |c2|<br>
next if c2 == 0x7f<br>
cp932 = [c1, c2].pack("C*")<br>
cp50221 = NKF.nkf("-m0x --ic=cp932 --oc=cp50221", cp932)<br>
cp932_bak = NKF.nkf("-m0x --ic=cp50221 --oc=cp932", cp50221)<br>
if cp932_bak.empty?<br>
puts [cp932.unpack("H*"), cp50221.unpack("H*")].join(" ")<br>
end<br>
end<br>
end</p>
Ruby master - Bug #6716 (Closed): FileUtils.mv でリンク先がないシンボリックリンクファイルを指定すると ENOENT エラーになる
https://redmine.ruby-lang.org/issues/6716
2012-07-10T19:27:31Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>FileUtils.mv でリンク先がないシンボリックリンクファイルを指定すると ENOENT になります。</p>
<pre><code> % ln -s unexist hoge
% ruby -v -rfileutils -e 'FileUtils.mv("hoge", "fuga")'
ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux]
/home/tommy/ruby193/lib/ruby/1.9.1/fileutils.rb:1515:in `stat': No such file or directory - hoge (Errno::ENOENT)
from /home/tommy/ruby193/lib/ruby/1.9.1/fileutils.rb:1515:in `block in fu_each_src_dest'
from /home/tommy/ruby193/lib/ruby/1.9.1/fileutils.rb:1531:in `fu_each_src_dest0'
from /home/tommy/ruby193/lib/ruby/1.9.1/fileutils.rb:1513:in `fu_each_src_dest'
from /home/tommy/ruby193/lib/ruby/1.9.1/fileutils.rb:508:in `mv'
from -e:1:in `<main>'
</code></pre>
<p>mv コマンドと同じ動きを目指すのであればエラーにすべきではないと思います。</p>
<p>r27317 から発生していると思います。</p>
Backport192 - Backport #5731 (Rejected): enum_for を使うと method_missing にブロックが渡されない
https://redmine.ruby-lang.org/issues/5731
2011-12-09T10:26:45Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>次のスクリプトを 1.9.3 で実行すると enum_for の方は block が nil になります。<br>
1.8.7 では両方とも block が渡されました。</p>
<hr>
<p>class A<br>
def method_missing(name, *args, &block)<br>
p block<br>
end<br>
end</p>
<h2>a = A.new<br>
a.hoge{|l| p l} # ブロックが渡される<br>
a.enum_for(:hoge).each{|l| p l} # ブロックが渡されない</h2>
<p>% /usr/local/ruby187/bin/ruby -v a.rb<br>
ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]<br>
#<a href="Proc:0xb76dbb60@a.rb:9" class="external">Proc:0xb76dbb60@a.rb:9</a><br>
#<a href="Proc:0xb76db8e0@a.rb:10" class="external">Proc:0xb76db8e0@a.rb:10</a></p>
<p>% ruby -v a.rb<br>
ruby 1.9.3p0 (2011-10-30) [i686-linux]<br>
#<a href="Proc:0x8829080@a.rb:9" class="external">Proc:0x8829080@a.rb:9</a><br>
nil</p>
<a name="使い方が間違ってるだけだったらすいません"></a>
<h1 >使い方が間違ってるだけだったらすいません<a href="#使い方が間違ってるだけだったらすいません" class="wiki-anchor">¶</a></h1>
Backport193 - Backport #5635 (Closed): String#unpack("M") の不正データ時の振る舞い
https://redmine.ruby-lang.org/issues/5635
2011-11-15T15:51:33Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>String#unpack("M") で "=hoge" みたいな不正なデータがあった場合、現在は<br>
そこで処理を中断してしまっていますが、それ以降のデータをすべて捨ててし<br>
まうのはかわいそうなので、ポインタを一つ進めて処理を継続した方がいいん<br>
じゃないかと思うのですがどうでしょうか。</p>
<p>RFC2045 には次のような記述があります。</p>
<pre><code>(2) An "=" followed by a character that is neither a
hexadecimal digit (including "abcdef") nor the CR
character of a CRLF pair is illegal. This case can be
the result of US-ASCII text having been included in a
quoted-printable part of a message without itself
having been subjected to quoted-printable encoding. A
reasonable approach by a robust implementation might be
to include the "=" character and the following
character in the decoded data without any
transformation and, if possible, indicate to the user
that proper decoding was not possible at this point in
the data.
</code></pre>
<a name="Index-packc"></a>
<h1 >Index: pack.c<a href="#Index-packc" class="wiki-anchor">¶</a></h1>
<p>--- pack.c (リビジョン 33758)<br>
+++ pack.c (作業コピー)<br>
@@ -2008,20 +2008,23 @@</p>
<pre><code> while (s < send) {
if (*s == '=') {
</code></pre>
<ul>
<li>
<pre><code> if (++s == send) break;
</code></pre>
</li>
<li>
<pre><code> if (s+1 < send && *s == '\r' && *(s+1) == '\n')
</code></pre>
</li>
<li>
<pre><code> s++;
</code></pre>
</li>
<li>
<pre><code> if (*s != '\n') {
</code></pre>
</li>
<li>
<pre><code> if ((c1 = hex2num(*s)) == -1) break;
</code></pre>
</li>
<li>
<pre><code> if (++s == send) break;
</code></pre>
</li>
<li>
<pre><code> if ((c2 = hex2num(*s)) == -1) break;
</code></pre>
</li>
<li>
<pre><code> *ptr++ = c1 << 4 | c2;
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if (s+1 < send && *(s+1) == '\n') {
</code></pre>
</li>
<li>
<pre><code> s += 2;
</code></pre>
</li>
<li>
<pre><code> continue;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> if (s+2 < send) {
</code></pre>
</li>
<li>
<pre><code> if (*(s+1) == '\r' && *(s+2) == '\n') {
</code></pre>
</li>
<li>
<pre><code> s += 3;
</code></pre>
</li>
<li>
<pre><code> continue;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> if ((c1 = hex2num(*(s+1))) > -1 && (c2 = hex2num(*(s+2))) > -1) {
</code></pre>
</li>
<li>
<pre><code> *ptr++ = c1 << 4 | c2;
</code></pre>
</li>
<li>
<pre><code> s += 3;
</code></pre>
</li>
<li>
<pre><code> continue;
</code></pre>
</li>
<li>
<pre><code> }
}
}
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> else {
</code></pre>
</li>
<li>
<pre><code> *ptr++ = *s;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> s++;
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> *ptr++ = *s++;
}
rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
ENCODING_CODERANGE_SET(buf, rb_ascii8bit_encindex(), ENC_CODERANGE_VALID);
</code></pre>
</li>
</ul>
<a name="Index-testrubytest_packrb"></a>
<h1 >Index: test/ruby/test_pack.rb<a href="#Index-testrubytest_packrb" class="wiki-anchor">¶</a></h1>
<p>--- test/ruby/test_pack.rb (リビジョン 33758)<br>
+++ test/ruby/test_pack.rb (作業コピー)<br>
@@ -612,6 +612,17 @@<br>
assert_equal([0x100000000], "\220\200\200\200\000".unpack("w"), [0x100000000])<br>
end</p>
<ul>
<li>def test_pack_unpack_M</li>
<li>assert_equal(["pre123after"], "pre=31=32=33after".unpack("M"))</li>
<li>assert_equal(["preafter"], "pre=\nafter".unpack("M"))</li>
<li>assert_equal(["preafter"], "pre=\r\nafter".unpack("M"))</li>
<li>assert_equal(["pre="], "pre=".unpack("M"))</li>
<li>assert_equal(["pre=\r"], "pre=\r".unpack("M"))</li>
<li>assert_equal(["pre=hoge"], "pre=hoge".unpack("M"))</li>
<li>assert_equal(["pre=1after"], "pre==31after".unpack("M"))</li>
<li>assert_equal(["pre==1after"], "pre===31after".unpack("M"))</li>
<li>end</li>
<li>def test_modify_under_safe4<br>
s = "foo"<br>
assert_raise(SecurityError) do</li>
</ul>
Backport187 - Backport #5105 (Closed): CGI::Session#session_id の生成方法について
https://redmine.ruby-lang.org/issues/5105
2011-07-27T12:48:34Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>とみたです。</p>
<p>古い話ですが、 r13672 で CGI::Session#session_id が SecureRandom が生成<br>
した乱数を単純に使用するようになっています。それまではタイムスタンプ &<br>
プロセスID & 乱数 & 固定文字から生成した MD5 ダイジェスト値が使用されて<br>
いました。</p>
<p>このように生成した MD5 ダイジェスト値よりも、単純に乱数をそのまま使用す<br>
る方が重複が発生しやすくなってしまっているんじゃないかと思うのですがど<br>
うでしょう。</p>
<p>というか、実際に重複が発生してしまったので。</p>
<p>以下、SecureRandom を使いつつ元の挙動に戻すパッチです。</p>
<p>--- lib/cgi/session.rb.orig 2009-02-20 19:35:11.000000000 +0900<br>
+++ lib/cgi/session.rb 2011-07-27 12:27:57.000000000 +0900<br>
@@ -25,6 +25,8 @@</p>
<p>require 'cgi'<br>
require 'tmpdir'<br>
+require 'securerandom'<br>
+require 'digest/md5'</p>
<p>class CGI</p>
<p>@@ -174,21 +176,15 @@<br>
# is used internally for automatically generated<br>
# session ids.<br>
def create_new_id</p>
<ul>
<li>
<pre><code> require 'securerandom'
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> session_id = SecureRandom.hex(16)
</code></pre>
</li>
<li>
<pre><code> rescue NotImplementedError
</code></pre>
</li>
<li>
<pre><code> require 'digest/md5'
</code></pre>
</li>
<li>
<pre><code> md5 = Digest::MD5::new
</code></pre>
</li>
<li>
<pre><code> now = Time::now
</code></pre>
</li>
<li>
<pre><code> md5.update(now.to_s)
</code></pre>
</li>
<li>
<pre><code> md5.update(String(now.usec))
</code></pre>
</li>
<li>
<pre><code> md5.update(String(rand(0)))
</code></pre>
</li>
<li>
<pre><code> md5.update(String($$))
</code></pre>
</li>
<li>
<pre><code> md5.update('foobar')
</code></pre>
</li>
<li>
<pre><code> session_id = md5.hexdigest
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> session_id
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> r = SecureRandom.random_bytes(16) rescue rand(0).to_s
</code></pre>
</li>
<li>
<pre><code> md5 = Digest::MD5::new
</code></pre>
</li>
<li>
<pre><code> now = Time::now
</code></pre>
</li>
<li>
<pre><code> md5.update(now.to_s)
</code></pre>
</li>
<li>
<pre><code> md5.update(String(now.usec))
</code></pre>
</li>
<li>
<pre><code> md5.update(r)
</code></pre>
</li>
<li>
<pre><code> md5.update(String($$))
</code></pre>
</li>
<li>
<pre><code> md5.update('foobar')
</code></pre>
</li>
<li>
<pre><code> md5.hexdigest
</code></pre>
end<br>
private :create_new_id</li>
</ul>
Backport187 - Backport #2187 (Closed): Net::IMAP::ResponseParseError
https://redmine.ruby-lang.org/issues/2187
2009-10-09T23:01:55Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>=begin<br>
とみたです。</p>
<p>RFC 3501 の resp-text-code は次のようになっていて atom だけでも OK なはずなのですが、</p>
<p>resp-text-code = "ALERT" /<br>
"BADCHARSET" [SP "(" astring *(SP astring) ")" ] /<br>
capability-data / "PARSE" /<br>
"PERMANENTFLAGS" SP "("<br>
[flag-perm <em>(SP flag-perm)] ")" /<br>
"READ-ONLY" / "READ-WRITE" / "TRYCREATE" /<br>
"UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /<br>
"UNSEEN" SP nz-number /<br>
atom [SP 1</em><any TEXT-CHAR except "]">]</p>
<p>net/imapd.rb の ResponseParser#resp_text_code() は atom の後に SP と TEXT が<br>
必須になってしまっていて、"* OK [CLOSED] Previous mailbox closed." のような応答で<br>
エラーになってしまいます。</p>
<p>/usr/local/ruby-1.8.7/lib/ruby/1.8/net/imap.rb:3124:in `parse_error': unexpected token RBRA (expected SPACE) (Net::IMAP::ResponseParseError)</p>
<p>次のパッチで直ると思います。</p>
<a name="イマイチ綺麗じゃないですけど"></a>
<h1 >イマイチ綺麗じゃないですけど…<a href="#イマイチ綺麗じゃないですけど" class="wiki-anchor">¶</a></h1>
<a name="Index-libnetimaprb"></a>
<h1 >Index: lib/net/imap.rb<a href="#Index-libnetimaprb" class="wiki-anchor">¶</a></h1>
<p>--- lib/net/imap.rb (revision 25262)<br>
+++ lib/net/imap.rb (working copy)<br>
@@ -2764,7 +2764,10 @@<br>
match(T_SPACE)<br>
result = ResponseCode.new(name, number)<br>
else</p>
<ul>
<li>
<pre><code> match(T_SPACE)
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if match(T_SPACE, T_RBRA).symbol == T_RBRA
</code></pre>
</li>
<li>
<pre><code> @lex_state = EXPR_RTEXT
</code></pre>
</li>
<li>
<pre><code> return ResponseCode.new(name, nil)
</code></pre>
</li>
<li>
<pre><code> end
@lex_state = EXPR_CTEXT
token = match(T_TEXT)
@lex_state = EXPR_BEG
</code></pre>
</li>
</ul>
<p>=end</p>
Backport187 - Bug #1957 (Closed): NKF.nkf でシフトJISの "\e" が "" に変換される
https://redmine.ruby-lang.org/issues/1957
2009-08-19T10:25:41Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>=begin<br>
とみたです。</p>
<p>NKF.nkf で -S 指定して "\e" を変換すると "" になってしまいます。</p>
<p>$ ruby -v -r nkf -e 'p NKF.nkf("-Ss", "\e")'<br>
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-linux]<br>
""</p>
<p>-Se でも -Sw でも同じです。-Es や -Ws では問題ありません。</p>
<p>$ ruby -v -r nkf -e 'p NKF.nkf("-Es", "\e")'<br>
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-linux]<br>
"\e"</p>
<p>\e が文字列の一部である場合は問題ありません。</p>
<p>$ ruby -v -r nkf -e 'p NKF.nkf("-Ss", "\e123")'<br>
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-linux]<br>
"\e123"<br>
=end</p>
Backport191 - Backport #1789 (Closed): TCPSocket#read returns untainted string
https://redmine.ruby-lang.org/issues/1789
2009-07-19T17:20:33Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>=begin<br>
とみたです。</p>
<p>TCPSocket#read が untainted 文字列を返します。</p>
<p>$ ruby -v -rsocket -e 'p TCPSocket.new("localhost",25).read(4).tainted?'<br>
ruby 1.9.2dev (2009-07-19 trunk 24201) [i686-linux]<br>
false</p>
<p>1.8.7 では tainted です。</p>
<p>$ ruby -v -rsocket -e 'p TCPSocket.new("localhost",25).read(4).tainted?'<br>
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]<br>
true</p>
<p>ちなみに TCPSocket#gets は tainted になります。</p>
<p>$ /usr/local/ruby-1.9.1/bin/ruby -v -rsocket -e 'p TCPSocket.new("localhost",25).gets.tainted?'<br>
ruby 1.9.2dev (2009-07-19 trunk 24201) [i686-linux]<br>
true<br>
=end</p>
Backport187 - Backport #1196 (Closed): 正規表現の \s と [\s] が異なる
https://redmine.ruby-lang.org/issues/1196
2009-02-23T18:31:21Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>=begin<br>
正規表現の \s には \v が含まれませんが、[\s] には \v が含まれるようです。</p>
<p>$ ruby -v -e 'p "\v" =~ /\s/'<br>
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]<br>
nil<br>
$ ruby -v -e 'p "\v" =~ /[\s]/'<br>
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]<br>
0</p>
<p>以下のパッチで直ると思います。</p>
<p>--- regex.c.orig 2008-08-04 14:15:15.000000000 +0900<br>
+++ regex.c 2009-02-23 18:17:57.000000000 +0900<br>
@@ -2244,6 +2244,7 @@<br>
SET_LIST_BIT('\n');<br>
SET_LIST_BIT('\r');<br>
SET_LIST_BIT('\f');</p>
<ul>
<li>
<pre><code> SET_LIST_BIT('\v');
}
else {
char cc;
</code></pre>
</li>
</ul>
<p>=end</p>
Ruby master - Bug #1075 (Rejected): \r\n と \n が混在した CSV がエラーになる
https://redmine.ruby-lang.org/issues/1075
2009-01-31T18:58:32Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>=begin<br>
"a,"b\n",c\r\n" を CSV.new に渡すとエラーになります。</p>
<p>$ ruby -v -rcsv -e 'p CSV.parse("a,"b\n",c\r\n")'<br>
ruby 1.9.1p0 (2009-01-30 revision 21907) [i686-linux]<br>
/usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1863:in <code>block (2 levels) in shift': Unquoted fields do not allow \r or \n (line 1). (CSV::MalformedCSVError) from /usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1853:in </code>gsub!'<br>
from /usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1853:in <code>block in shift' from /usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1815:in </code>loop'<br>
from /usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1815:in <code>shift' from /usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1760:in </code>each'<br>
from /usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1771:in <code>to_a' from /usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1771:in </code>read'<br>
from /usr/local/ruby-1.9.1/lib/ruby/1.9.1/csv.rb:1360:in <code>parse' from -e:1:in </code>'</p>
<p>1.8.7 ではエラーになりません。</p>
<p>$ ruby -v -rcsv -e 'p CSV.parse("a,"b\n",c\r\n")'<br>
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]<br>
[["a", "b\n", "c"]]<br>
=end</p>
Ruby master - Bug #831 (Closed): make clean がエラーになる
https://redmine.ruby-lang.org/issues/831
2008-12-06T15:13:49Z
tommy (Masahiro Tomita)
tommy@tmtm.org
<p>=begin<br>
ruby-1.9.1-preview2 で configure 後 make clean するとエラーになります。</p>
<p>$ make clean<br>
sed 's/{$([^(){}]<em>)[^{}]</em>}//g' common.mk > uncommon.mk<br>
make[1]: ディレクトリ <code>/misc/tmp/ruby-1.9.1-preview2' に入ります make[1]: RM@: コマンドが見つかりませんでした make[1]: *** [clean] エラー 127 make[1]: ディレクトリ </code>/misc/tmp/ruby-1.9.1-preview2' から出ます<br>
make: [clean-enc] エラー 2 (無視されました)</p>
<p>環境は Ubuntu 8.10 です。<br>
=end</p>