TypeScriptは静的型付け言語なのかという話

この辺の話。

(中略)

これ、私はtestを呼び出す際にanyからの暗黙のキャストが入っているという理解なのですよね。 こういうイメージ。

const test = (f: string) => console.log(typeof f);
const foo: any = [1];
test(foo as string);

こういう互換性のないキャストがエラーもなくできてしまうという意味で弱い型付けなのではないかと。

最後書いているように、若干極論ではありますが、C/C++でポインタだとキャストしてしまえばなんでも渡せてしまうよね、という話はありますしね。

#include <iostream>
#include <typeinfo>
#include <cstdlib>
#include <cxxabi.h>

static char* buffer = 0;
static size_t bufferSize = 0;

static const std::string getTypeName(const std::type_info& type)
{
    int status;
    char* name = abi::__cxa_demangle(type.name(), buffer, &bufferSize, &status);
    if (name && status == 0) {
        std::string s(name);
        buffer = name;

        return s;
    }

    return "";
}

__attribute__((destructor))
static void cleanup()
{
    if (buffer) {
        free(buffer);
    }
}

class Foo
{
public:
  virtual void method() {}
};

class Bar : public Foo {};

class Baz
{
public:
  virtual void method() {}
};

void test(const Foo* p)
{
    std::cout << getTypeName(typeid(*p)) << std::endl;
}


int main()
{
    Foo foo;
    Bar bar;
    Baz baz;

    test(&foo); // Foo
    test(&bar); // Bar
    test(reinterpret_cast<Foo *>(&baz)); // Baz

    return 0;
}

まぁ、暗黙的にanyからキャストされてしまうTypeScriptと明示的なキャストが必要なC/C++を同列に語るのも乱暴といえば乱暴ではあります。 ただ、いずれにしても他の静的型付け言語で備えているような機能を一部備えていないとしても、TypeScriptの型システムのほとんどは静的なチェックなので、静的型付けと呼ぶしかないような気がします。 C++のdynamic_castやJavaでのダウンキャストは動的な型チェックでもあったりするので、そもそも無理に分類する必要もないんじゃないかという話もありますけど。

「都税クレジットカードお支払いサイト」不正アクセス事件の調査報告書

ざっとしか読んでないですが。

GMO-PG では、2008 年 12 月に最初の PCI DSS 認証を取得し、年次での再認証監査を 8 回経た上で、2016 年 12 月に最新の認証を取得しており、クレジットカード情報 を取扱う事業者として要求されるべき一定レベルの情報セキュリティ体制を具備して いたものの、本件ではそのような体制が Apache Struts 2 の未知の脆弱性を突いたゼロデイ攻撃に対しては、奏功しなかったという事案である。

S2-045は脆弱性情報公開と同時に対策済みバージョンがリリースされているので、そもそもゼロデイ攻撃じゃないよね。8、9ページの時系列の情報の所にもApache Struts 2の対策済みバージョンリリースの情報が出てこないのはミスリードしたいんでしょうかね。

とはいえ、セキュリティ情報提供サービスからのS2-045の情報提供自体が遅いとか危険度情報がないとかかわいそうな感じがしなくもない。大量の脆弱性情報をひとつひとつ精査はしてられないだろうしな。リモートコード実行(RCE)とか書いていたなら、危機感もてよ、という感じもありますが。

Oracle vs Googleのやつ

単純に疑問に思ったことなど。

Androidの非互換性

従来Javaと非互換な実装で、従来Javaのエコシステムが破壊されてんの?私が知らないだけで、今時のJavaライブラリは#ifdefみたいに、VM実装確認してスイッチしたりしてるんだろうか。
Javaと非互換の癖にJava名乗るなみたいな話であれば、それはそれでわかる。

トップレベルパッケージ

Android はまず、名前衝突を避けるために定められたパッケージ名の naming convention を完全に無視し、勝手に android というトップレベル・パッケージ名を宣言しました。

Android以外にもパッケージにドメイン名を入れない例は多い。ぱっと思いつく例だと、Groovyとか、Wekaとか、OpenNLPとか。
OSSなので、組織名入れたくないみたいな、事情はあるかもしれない。だったら、org.androidでいいんじゃね、という気もしますが。

OSSとして

OpenJDKをGPLでリリースしておいて、その一部であるAPIを無断使用として訴えるというのはどゆことだろ。まぁ、AndroidはOpenJDKではなく、Apache Harmonyの派生なので、そんな単純でもないが、Apache Harmonyを放置しておいて、Apache Harmony派生のAndroidだけ訴えるというのは、それこそ道義的にどうなんだ、という気はする。
仮にOpenJDKの派生として作られたら、GPLに従っている限りは文句を言われる筋合いはないはずだよね。

その他

AndroidのString.indexOf が壊れている件はソースを見る限り、Apache Harmonyから引き継いだバグっぽいですね。

git の sha1_to_hex のやつ

すこし調べた。

Linus が普通に Mailing List で明言していた。

Nothing magical, it's just "rounded up from 40 + NUL character".

単に、40バイト+NUL文字用の1バイトで切り上げて50バイトらしい。

が、masterのやつを見たら全然違うので、もう少し歴史を見てみる。
最初のは read-cache.c にあった。initial commitですね。

char * sha1_to_hex(unsigned char *sha1)
{
	static char buffer[50];
	static const char hex[] = "0123456789abcdef";
	char *buf = buffer;
	int i;

	for (i = 0; i < 20; i++) {
		unsigned int val = *sha1++;
		*buf++ = hex[val >> 4];
		*buf++ = hex[val & 0xf];
	}
	return buffer;
}

sha1_file.cに移動されたあと、ちゃんと毎回 NUL terminate されるようになる。commitは@1e80e0

char * sha1_to_hex(const unsigned char *sha1)
{
	static char buffer[50];
	static const char hex[] = "0123456789abcdef";
	char *buf = buffer;
	int i;

	for (i = 0; i < 20; i++) {
		unsigned int val = *sha1++;
		*buf++ = hex[val >> 4];
		*buf++ = hex[val & 0xf];
	}
	*buf = '\0';

	return buffer;
}

static 領域のアドレスを返すためにエラーメッセージ作るのが面倒だとかそんな感じの文句が出たのか、簡易LRUキャッシュが導入される。commitは@dcb345

char * sha1_to_hex(const unsigned char *sha1)
{
	static int bufno;
	static char hexbuffer[4][50];
	static const char hex[] = "0123456789abcdef";
	char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
	int i;

	for (i = 0; i < 20; i++) {
		unsigned int val = *sha1++;
		*buf++ = hex[val >> 4];
		*buf++ = hex[val & 0xf];
	}
	*buf = '\0';

	return buffer;
}

さらに hex.c に移動して、マジックナンバーをマクロで置き換え、バッファサイズも変更。commit は @aa1c6f

char *sha1_to_hex(const unsigned char *sha1)
{
	static int bufno;
	static char hexbuffer[4][GIT_SHA1_HEXSZ + 1];
	static const char hex[] = "0123456789abcdef";
	char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
	int i;

	for (i = 0; i < GIT_SHA1_RAWSZ; i++) {
		unsigned int val = *sha1++;
		*buf++ = hex[val >> 4];
		*buf++ = hex[val & 0xf];
	}
	*buf = '\0';

	return buffer;
}
#define GIT_SHA1_RAWSZ 20
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)

で、reentrant版の sha1_to_hex_r と非reentrant版のsha1_to_hexに分離して、だいたい今の形になっている。commitは@af49c6

char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
{
	static const char hex[] = "0123456789abcdef";
	char *buf = buffer;
	int i;

	for (i = 0; i < GIT_SHA1_RAWSZ; i++) {
		unsigned int val = *sha1++;
		*buf++ = hex[val >> 4];
		*buf++ = hex[val & 0xf];
	}
	*buf = '\0';

	return buffer;
}

char *sha1_to_hex(const unsigned char *sha1)
{
	static int bufno;
	static char hexbuffer[4][GIT_SHA1_HEXSZ + 1];
	return sha1_to_hex_r(hexbuffer[3 & ++bufno], sha1);
}

こんな小さな関数でも結構変わっているもんですな。

データがずれている

ブコメにも書いたけど国立大学の授業料のデータが5年ずれているっぽい。昭和50年は1975年ですからね。
というだけなのもなんなので、ちゃんとデータをまとめてみた。

1975年比でいうと、物価で補正すると8.26倍、給与で補正すると5.92倍になっとると。

注意点

  • 授業料のデータは文科省のページから
  • 物価は政府統計から「持家の家賃帰属を除く総合」
  • 給与は厚労省のページの所定内給与を使った
  • 1975年の所定内給与のデータがないようなので、1976年、1977年のデータから線形補間
  • 2006年以降の授業料のデータがなかったが、変わっていないようなので、2005年のデータのままとした
  • 一部手打ちしているので、間違っているかも