《lua源碼賞析》筆記 -2

 數據結構
 string :
短字符串  長字符串 
LUA_TSHRSTR      LUA_TLNGSTR
這個小類型區放在了 類型字節的 高四位,外部的API並不能看見 所以我們看到的只有LUA_STRING一種類型。
區分長短字符串的界限 由定義在 luaconf.h中的 宏 LUAI_MAXSHORTLEN來決定  默認設置爲40個字節。這個宏不能設置少於十個字節。
字符串一旦被創建了  便不可以被改寫。LUA的 值對象若是 字符串類型,那就以引用的形式存在。屬於需要被垃圾收集的對象。
一個字符串如果沒有任何一個地方引用他 就會被回收。
字符串類型被定義在lobject.h中。
typedef union TSring{
L_Umaxalign dummy;  / ensures maximum alignment for string /
struct{
 CommonHeader; --用於GC
 lu_byte extra; --用來記錄輔助信息。
 unsigned int hash;    --記錄字符串的hash 可以用來加速字符串的匹配和查找。
 size_t len; --lua不是用/0來記錄接未的 所以要一個len域來記錄字符串的長度。
}tsv;
}TSring;
字符串的數據內容沒有被分配出一個獨立的內存來保存,而是直接追加到了STstring的後面,用getstr這個宏就能夠直接拿出來。
#define getstr(ts) cast(const char *,(ts)+1)


所有的短字符串都被存放在了全局表(global_State)的str域中。strt是 string table的 簡寫,他是一個哈希表。
就是短字符串都放在 了一個全局的哈希表中。


lstate.h:stringtable
typedef stuct stringtable{
   GCObject **hash;
   lu_int32 nuse;
   int size;
}stringtable;


相同的短字符串在同一個 lua_state中只存在 唯一一份 ,被稱爲字符串的內部化。
長字符串則獨立 存放,從外部壓入一個長字符串的時候,先簡單複製一遍字符串,並不立即計算他的哈希值,而是標記一下extra域。知道需要對字符串做鍵匹配的時候,才惰性計算hash值,加快之後的鍵比較過程。


Hash Dos 
在lua 5.2.0之前,字符串是部分長短一律內部化後放在字符串表中的。
對於長字符串,爲了加快內部化的過程,計算長字符串哈希值是跳躍進行的。
在lua 5.2.0發佈後不久,有人在郵件列表中踢出,lua的這個設計可能給了別人攻擊Hash Dos的機會。
就爲了解決問題吧,就把長字符串給獨立了出來,大量文本處理中的輸入字符串不再通過哈希表內部化進入全局字符串表中了。與此同時使用了一個隨機種子用於哈希值的計算。
這樣攻擊者就不容易輕易地構造出擁有和原來哈希值相同的不同字符串了。


字符串比較
比較兩個字符串是否相同,西安區別長短字符串。
長字符穿比較線比較長度 長度比較完了 之後逐字節比較 
短字符串經過了內部化, 直接比較對象地址就行。

所有的短字符串都被內部化放在了全局的字符串表中。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章