一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法及系統(tǒng)的制作方法
【專利摘要】本發(fā)明公開了一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法及系統(tǒng),其中,該方法包括:步驟1,建立與數(shù)據(jù)庫字典服務(wù)器的連接;步驟2,查詢數(shù)據(jù)庫字典表,獲取當(dāng)前數(shù)據(jù)庫用戶下的所有存儲過程對象,并構(gòu)建成為待檢測對象列表;步驟3,判斷待檢測對象列表中是否存在未檢測的對象,如果存在則對未檢測的對象的存儲過程進(jìn)行代碼解析,生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹;步驟4,根據(jù)步驟3生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果;步驟5,根據(jù)靜態(tài)檢測結(jié)果生成靜態(tài)檢測報(bào)告。
【專利說明】
一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法及系統(tǒng)
技術(shù)領(lǐng)域
[0001 ]本發(fā)明涉及靜態(tài)測試領(lǐng)域,,屬于計(jì)算機(jī)輔助靜態(tài)檢測技術(shù),具體來講,尤指一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法及系統(tǒng)。
【背景技術(shù)】
[0002]靜態(tài)測試是指被測試程序不在機(jī)器上運(yùn)行,而采用人工檢測和計(jì)算機(jī)輔助靜態(tài)檢測的手段對文檔或程序進(jìn)行檢測。隨著計(jì)算機(jī)技術(shù)的不斷發(fā)展和軟件規(guī)模的不斷擴(kuò)大,計(jì)算機(jī)輔助靜態(tài)檢測已成為程序靜態(tài)測試最主要手段。計(jì)算機(jī)輔助靜態(tài)檢測是指通過詞法分析、語法分析等技術(shù)對程序代碼進(jìn)行掃描,進(jìn)而檢測代碼的語法、結(jié)構(gòu)、過程、接口等來驗(yàn)證代碼是否滿足規(guī)范性、安全性、可靠性、可維護(hù)性等指標(biāo)的一種代碼檢測技術(shù)。相對于人工檢測,計(jì)算機(jī)輔助靜態(tài)檢測具有效率高、成本低、覆蓋面廣的優(yōu)勢。
[0003]近十幾年間,國外已涌現(xiàn)出許多面向主流編程語言的靜態(tài)檢測工具,例如面向Java 代碼的Findbugs、PMD 和Checksty Ie工具,面向 C/C++代碼的K 1cwork、Po Iy Spacee工具,面向Oracle存儲過程的SonarCuber工具等。國內(nèi)也有相關(guān)專利發(fā)明,例如徐國愛提出的面向主流編程語言的《基于源代碼靜態(tài)分析的軟件安全代碼分析單元及其檢測方法》等。這些工具和方法的共同特點(diǎn)是以代碼文件為掃描對象,這種方式對于數(shù)據(jù)庫存儲過程來說,存在許多缺陷,限制了靜態(tài)檢測能力。以SonarCuber工具為例,由于缺少存儲過程所涉及的表結(jié)構(gòu)信息,所以無法檢查WHERE條件中的隱式轉(zhuǎn)換、無法判斷SELECT INTO語句是否存在字符串長度溢出風(fēng)險(xiǎn)等,而這些檢查項(xiàng)恰恰是數(shù)據(jù)庫存儲過程中非常重要的靜態(tài)檢測內(nèi)容。究其原因,主要因?yàn)榇鎯^程靜態(tài)檢測所需信息不只包含在代碼文件中,還分散在其他數(shù)據(jù)庫數(shù)據(jù)字典(以下簡稱數(shù)據(jù)庫字典)中。數(shù)據(jù)庫字典是數(shù)據(jù)庫的重要組成部分。它存放有數(shù)據(jù)庫有關(guān)的所有信息,對數(shù)據(jù)庫用戶來說是一組只讀的表或視圖。數(shù)據(jù)庫字典內(nèi)容包括:數(shù)據(jù)庫中所有模式對象的信息(如表、視圖、索引、存儲過程等)、模式對象的關(guān)聯(lián)信息(如存儲過程所引用的模式對象)、用戶及角色被授予的權(quán)限等。由此可見,通過數(shù)據(jù)庫字典可以更加全面地獲取存儲過程信息,為此亟需設(shè)計(jì)一種基于數(shù)據(jù)庫字典的新靜態(tài)檢測方法及系統(tǒng)。
【發(fā)明內(nèi)容】
[0004]有鑒于此,本發(fā)明目的是提供一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法及系統(tǒng),可以克服現(xiàn)有存儲過程的靜態(tài)檢測工具和方法的局限性,全面提升存儲過程靜態(tài)檢測的能力。其中,本發(fā)明所指的存儲過程泛指通過數(shù)據(jù)庫過程語言編寫的程序,包括程序包、存儲過程和函數(shù)等。目前主流的數(shù)據(jù)庫DB2、0racle、SQLSerVer、MySQL都已支持存儲過程。
[0005]為達(dá)到上述目的,本發(fā)明提出了一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法,該方法包括:步驟I,建立與數(shù)據(jù)庫字典服務(wù)器的連接;步驟2,查詢數(shù)據(jù)庫字典表,獲取當(dāng)前數(shù)據(jù)庫用戶下的所有存儲過程對象,并構(gòu)建成為待檢測對象列表;步驟3,判斷待檢測對象列表中是否存在未檢測的對象,如果存在則對未檢測的對象的存儲過程進(jìn)行代碼解析,生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹;步驟4,根據(jù)步驟3生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果;步驟5,根據(jù)靜態(tài)檢測結(jié)果生成靜態(tài)檢測報(bào)告。
[0006]進(jìn)一步的,在步驟2中,存儲過程對象包括:程序包、獨(dú)立存儲過程、獨(dú)立函數(shù)、表結(jié)構(gòu)、自定義類型。
[0007]進(jìn)一步的,在步驟3中,判斷待檢測對象列表中是否存在未檢測的對象,如果有則對未檢測的對象的存儲過程進(jìn)行代碼解析,生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹,包括:步驟301,判斷待檢測對象列表中是否存在未檢測的對象,如果有則進(jìn)入步驟302,如果沒有進(jìn)入步驟308;步驟302,根據(jù)未檢測對象的對象類型,判斷未檢測對象的對象信息是否在數(shù)據(jù)庫字典中,如果是則跳轉(zhuǎn)至步驟307,否則跳轉(zhuǎn)至步驟303;步驟303,從數(shù)據(jù)庫字典中獲取引用對象的代碼;步驟304,使用詞法分析組件對引用對象的代碼進(jìn)行詞法分析,獲取記號流;步驟305,使用語法分析組件分析記號流生成語法樹;步驟306,遍歷語法樹,將代碼中的聲明提取為符號,將符號添加至全局符號樹中,跳轉(zhuǎn)至步驟301;步驟307,從數(shù)據(jù)庫字典表中直接獲取對象信息,將對象信息添加至全局符號樹中,跳轉(zhuǎn)至步驟301;步驟308,從數(shù)據(jù)庫字典中獲取存儲過程對象的代碼;步驟309,對存儲過程對象的代碼進(jìn)行詞法分析,形成存儲過程對象的記號流;步驟310,對存儲過程對象的記號流進(jìn)行注釋分析,獲得注釋表;步驟311,對存儲過程對象的記號流進(jìn)行語法分析,生成語法樹。
[0008]進(jìn)一步的,在步驟4中,根據(jù)步驟3生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果,包括:步驟401,將當(dāng)前節(jié)點(diǎn)設(shè)置為根節(jié)點(diǎn);步驟402,判斷當(dāng)前節(jié)點(diǎn)是否表示新作用域,如果是新作用域則跳轉(zhuǎn)至步驟403,否則跳轉(zhuǎn)至步驟404;步驟403,將新的空符號表通過局部符號管理組件壓入局部符號棧中;步驟404,判斷當(dāng)前節(jié)點(diǎn)是不是新符號,如果是新符號則跳轉(zhuǎn)至步驟405,否則跳轉(zhuǎn)至步驟406;步驟405,將符號添加至局部符號堆棧中;步驟406,調(diào)用靜態(tài)檢測組件,進(jìn)行靜態(tài)檢測預(yù)處理,進(jìn)行變量使用前必須賦值的檢查時,標(biāo)識變量符號被初始化狀態(tài);步驟407,判斷是否還存在未訪問的子節(jié)點(diǎn),如果是,則跳轉(zhuǎn)至步驟408,否則,跳轉(zhuǎn)至步驟411;步驟408,將當(dāng)前節(jié)點(diǎn)壓入節(jié)點(diǎn)棧中;步驟409,將當(dāng)前節(jié)點(diǎn)設(shè)為最左的未訪問子節(jié)點(diǎn);步驟410,將步驟408所取得子節(jié)點(diǎn)標(biāo)識為已訪問,跳轉(zhuǎn)至步驟402;步驟411,訪問完子節(jié)點(diǎn)后,再次調(diào)用靜態(tài)檢測組件,進(jìn)行代碼檢查和度量,在檢查和度量過程中,通過訪問局部符號棧與全局符號樹獲取符號信息,通過訪問注釋表獲取注釋信息;步驟412,判斷當(dāng)前節(jié)點(diǎn)是否表示新作用域,如果是,則跳轉(zhuǎn)至413,否則跳轉(zhuǎn)至415;步驟413,從局部符號棧中彈出符號表;步驟414,判斷節(jié)點(diǎn)棧是否為空,如果是,則表示語法樹遍歷結(jié)束。
[0009]進(jìn)一步的,在步驟414中,如果判斷節(jié)點(diǎn)棧不為空,跳轉(zhuǎn)至步驟415;步驟415,從節(jié)點(diǎn)棧中取出一個節(jié)點(diǎn),并賦給當(dāng)前節(jié)點(diǎn),跳轉(zhuǎn)至步驟402。
[0010]進(jìn)一步的,在步驟402中的新作用域產(chǎn)生于存儲過程的起始位置、SQL語句的起始位置。
[0011]進(jìn)一步的,在步驟404中的新符號產(chǎn)生于存儲過程定義、變量定義、類型定義。
[0012]為達(dá)到上述目的,本發(fā)明還提出了一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測系統(tǒng),該系統(tǒng)包括:數(shù)據(jù)庫訪問單元,用于建立與數(shù)據(jù)庫字典服務(wù)器的連接;查詢單元,用于查詢數(shù)據(jù)庫字典表,獲取當(dāng)前數(shù)據(jù)庫用戶下的所有存儲過程對象,并構(gòu)建成為待檢測對象列表;代碼解析單元,用于判斷待檢測對象列表中是否存在未檢測的對象,如果有則對未檢測的對象的存儲過程進(jìn)行代碼解析,生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹;代碼檢測單元,用于根據(jù)生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果;報(bào)告生成單元,用于根據(jù)靜態(tài)檢測結(jié)果生成靜態(tài)檢測報(bào)告。
[0013]進(jìn)一步的,所述代碼解析單元包括:詞法分析組件、語法分析組件、注釋管理組件和全局符號管理組件;其中,詞法分析組件,用于對輸入的代碼字符流進(jìn)行逐個掃描,從字符中識別出標(biāo)識符、關(guān)鍵字、常量等相對獨(dú)立的記號,形成記號流;語法分析組件,用于在詞法分析組件輸出的記號流基礎(chǔ)上將獨(dú)立的記號根據(jù)語法文法組建為抽象語法樹;注釋管理組件,用于利用詞法分析組件輸出的記號流,構(gòu)造注釋表,記錄每一段注釋的起始、結(jié)束位置和注釋內(nèi)容;全局符號管理組件,用于通過分析存儲過程所引用的對象,利用數(shù)據(jù)庫字典和代碼解析,獲取符號的類別、數(shù)據(jù)類型等信息。
[0014]進(jìn)一步的,代碼檢測單元包括:局部符號管理組件和靜態(tài)檢測組件;其中,局部符號管理組件,用于負(fù)責(zé)管理局部符號桟,包括符號表入桟、符號表出桟、在桟頂符號表中添加符號;在抽象語法樹遍歷時,根據(jù)語義獲取符號信息,包括符號的類別、數(shù)據(jù)類型,屬于相同作用域的符號組織成局部符號表;靜態(tài)檢測組件,是一系列檢查組件和度量組件的集合,用于完成實(shí)際靜態(tài)測試任務(wù);檢查組件用于是檢查存儲過程是否存在缺陷或隱患,度量組件用于對存儲過程的整體質(zhì)量進(jìn)行評估。
[0015]本發(fā)明針對數(shù)據(jù)庫特點(diǎn),提出了一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法及系統(tǒng),相對于目前其他相關(guān)技術(shù),其突出優(yōu)點(diǎn)和有益效果是:
[0016]1、只需數(shù)據(jù)庫的連接信息和數(shù)據(jù)庫字典表的訪問權(quán)限即可完成存儲過程靜態(tài)檢測,改變現(xiàn)有靜態(tài)檢測方法對于代碼文件的依賴;
[0017]2、數(shù)據(jù)字典包含的儲過程代碼、表、視圖、類型等信息更加準(zhǔn)確和完整,這使得靜態(tài)檢測能力更加強(qiáng)大,可檢測WHERE條件中的隱式轉(zhuǎn)換、判斷SELECT INTO語句是否存在字符串長度溢出風(fēng)險(xiǎn)等;
[0018]3、對數(shù)據(jù)庫無限制,可支持目前所有的數(shù)據(jù)庫存儲過程,并具備對新的數(shù)據(jù)庫存儲過程的擴(kuò)充能力;
[0019]4、代碼與注釋的分離解析,既簡化了語法分析過程,又保留了代碼的完整信息,有利于針對注釋的靜態(tài)檢測組件的開發(fā);
[0020]5、主系統(tǒng)已解析出存儲過程所有信息,包括抽象語法樹、注釋庫與符號表,為復(fù)雜靜態(tài)檢測功能提供有效支持。
【附圖說明】
[0021]此處所說明的附圖用來提供對本發(fā)明的進(jìn)一步理解,構(gòu)成本申請的一部分,并不構(gòu)成對本發(fā)明的限定。在附圖中:
[0022]圖1為本發(fā)明一實(shí)施例的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法流程圖。
[0023]圖2為本發(fā)明一實(shí)施例的代碼解析步驟流程圖。
[0024]圖3為本發(fā)明一實(shí)施例的代碼檢測步驟流程圖。
[0025]圖4為本發(fā)明一實(shí)施例的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測系統(tǒng)結(jié)構(gòu)示意圖。
[0026]圖5為本發(fā)明一實(shí)施例的代碼解析單元的結(jié)構(gòu)示意圖。
[0027]圖6為本發(fā)明一實(shí)施例的代碼檢測單元的結(jié)構(gòu)示意圖。
【具體實(shí)施方式】
[0028]以下配合圖示及本發(fā)明的較佳實(shí)施例,進(jìn)一步闡述本發(fā)明為達(dá)成預(yù)定發(fā)明目的所采取的技術(shù)手段。
[0029]在本發(fā)明實(shí)施例中,涉及到一些術(shù)語的表述,此處先進(jìn)行說明如下:
[0030]1、抽象語法樹:簡稱為語法樹,是代碼的抽象語法結(jié)構(gòu)的樹狀表現(xiàn)形式。樹上的每個節(jié)點(diǎn)都表示代碼中的一種結(jié)構(gòu)。利用抽象語法樹可以大大降低靜態(tài)檢測方法的復(fù)雜度。
[0031]2、符號表:是靜態(tài)檢測的一個重要數(shù)據(jù)結(jié)構(gòu),它記錄了代碼中每個標(biāo)識符的類型、特征等相關(guān)信息。本發(fā)明中,符號表是一個字符串和信息的映射表,可以快速檢索符號的信息。同屬于某作用域的符號或者同屬于某對象的符號都會組織成一個符號表。
[0032]3、注釋表:一種用于保存代碼注釋的數(shù)據(jù)結(jié)構(gòu),建立了代碼行號與注釋的映射關(guān)系,可快速查詢到某行的注釋、某區(qū)間的數(shù)值及離某行最近的注釋等。注釋表的存在一方面是為提供代碼的完整信息,另一方面是簡化抽象語法樹的構(gòu)造。
[0033]4、全局符號樹:將符號表以樹狀形式組織,即符號與符號表之間建立從屬關(guān)系。通常情況下,根節(jié)點(diǎn)是模式符號,每個模式符號擁有子符號表,該符號表中存放著該模式下的對象符號,每個對象符號又擁有自己的子符號表。表、視圖、類型、存儲過程包聲明等符號都存放在全局符號樹中,而這些符號都來自數(shù)據(jù)庫字典,而非代碼本身。全局符號樹的作用是實(shí)現(xiàn)了存儲過程信息的完整性,為靜態(tài)檢測能力提升提供了保障。因此全局符號樹是本發(fā)明的重要特征。
[0034]5、局部符號棧:將符號表以堆棧形式組織,符號表根據(jù)作用域變化動態(tài)壓入堆棧或彈出堆棧。局部變量、內(nèi)部存儲過程都存放在局部符號表中。
[0035]結(jié)合圖1所示,為本發(fā)明一實(shí)施例的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法流程圖。如圖1所示,該方法包括:
[0036]步驟SI,建立與數(shù)據(jù)庫字典服務(wù)器的連接。
[0037]步驟S2,查詢數(shù)據(jù)庫字典表,獲取當(dāng)前數(shù)據(jù)庫用戶下的所有存儲過程對象,并構(gòu)建成為待檢測對象列表;其中,存儲過程對象包括:程序包、獨(dú)立存儲過程、獨(dú)立函數(shù)、表結(jié)構(gòu)、自定義類型。
[0038]步驟S3,判斷待檢測對象列表中是否存在未檢測的對象;如果存在則對未檢測的對象的存儲過程進(jìn)行代碼解析,生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹。如果不存在,則執(zhí)行步驟5。
[0039]步驟S4,根據(jù)步驟S3生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果。在執(zhí)行完步驟S4后,可以返回繼續(xù)執(zhí)行步驟3,來判斷是否還存在未檢測的對象,如果不存在,則進(jìn)一步執(zhí)行步驟5。
[0040]步驟S5,根據(jù)靜態(tài)檢測結(jié)果生成靜態(tài)檢測報(bào)告。
[0041]進(jìn)一步的,結(jié)合圖2所示,為本發(fā)明一實(shí)施例的代碼解析步驟流程圖。如圖2所示,在步驟S3中,代碼解析包括以下步驟:
[0042]步驟S301,判斷待檢測對象列表中是否存在未檢測的對象,如果有則進(jìn)入步驟302,如果沒有進(jìn)入步驟S308。
[0043]步驟S302,根據(jù)未檢測對象的對象類型,判斷未檢測對象的對象信息是否在數(shù)據(jù)庫字典中,如果是則跳轉(zhuǎn)至步驟S307,否則跳轉(zhuǎn)至步驟S303。
[0044]步驟S303,從數(shù)據(jù)庫字典中獲取引用對象的代碼。
[0045]步驟S304,使用詞法分析組件對引用對象的代碼進(jìn)行詞法分析,獲取記號流。
[0046]步驟S305,使用語法分析組件分析記號流生成語法樹。
[0047]步驟S306,遍歷語法樹,將代碼中的聲明提取為符號,將符號添加至全局符號樹中,跳轉(zhuǎn)至步驟S301。
[0048]步驟S307,從數(shù)據(jù)庫字典表中直接獲取對象信息,將對象信息添加至全局符號樹中,跳轉(zhuǎn)至步驟S301。
[0049]步驟S308,從數(shù)據(jù)庫字典中獲取存儲過程對象的代碼。
[0050]步驟S309,對存儲過程對象的代碼進(jìn)行詞法分析,形成存儲過程對象的記號流。
[0051]步驟S310,對存儲過程對象的記號流進(jìn)行注釋分析,獲得注釋表。
[0052]步驟S311,對存儲過程對象的記號流進(jìn)行語法分析,生成語法樹。
[0053]進(jìn)一步的,結(jié)合圖3所示,為本發(fā)明一實(shí)施例的代碼檢測步驟流程圖。如圖3所示,在步驟S4中,代碼檢測包括以下步驟:
[0054]步驟S401,將當(dāng)前節(jié)點(diǎn)設(shè)置為根節(jié)點(diǎn)。
[0055]步驟S402,判斷當(dāng)前節(jié)點(diǎn)是否表示新作用域,其中,新作用域產(chǎn)生于存儲過程的起始位置、SQL語句的起始位置;如果是新作用域則跳轉(zhuǎn)至步驟S403,否則跳轉(zhuǎn)至步驟S404。
[0056]步驟S403,將新的空符號表通過局部符號管理組件壓入局部符號棧中。
[0057]步驟S404,判斷當(dāng)前節(jié)點(diǎn)是不是新符號,新符號產(chǎn)生于存儲過程定義、變量定義、類型定義;如果是新符號則跳轉(zhuǎn)至步驟S405,否則跳轉(zhuǎn)至步驟S406。
[0058]步驟S405,將符號添加至局部符號堆棧中。
[0059]步驟S406,調(diào)用靜態(tài)檢測組件,進(jìn)行靜態(tài)檢測預(yù)處理,進(jìn)行變量使用前必須賦值的檢查時,標(biāo)識變量符號被初始化狀態(tài)。在執(zhí)行本步驟時,尚未訪問過子節(jié)點(diǎn),檢測組件可通過此步驟完成一些預(yù)處理,這在進(jìn)行復(fù)雜檢測時非常必要,比如進(jìn)行“變量使用前必須賦值”的檢查時,可以在本步驟就標(biāo)識變量符號是否被初始化,這樣在步驟S411只需簡單判斷表達(dá)式中的變量(即變量使用時)是否有初始化的標(biāo)識,如果有即可確認(rèn)變量使用時已被初始化。
[0060]步驟S407,判斷是否還存在未訪問的子節(jié)點(diǎn),如果是,則跳轉(zhuǎn)至步驟S408,否則,跳轉(zhuǎn)至步驟S411。
[0061 ] 步驟S408,將當(dāng)前節(jié)點(diǎn)壓入節(jié)點(diǎn)棧中。
[0062]步驟S409,將當(dāng)前節(jié)點(diǎn)設(shè)為最左的未訪問子節(jié)點(diǎn),最左是為保證子節(jié)點(diǎn)按從左至右順序訪問。子節(jié)點(diǎn)訪問順序?qū)τ谝恍㏒QL語句檢測比較重要,比如檢測SELECT語句時,一般先要確定語句操作對象,所以在編寫語法文法時,會將FROM子句作為最左子節(jié)點(diǎn),訪問時從左至右訪問。
[0063]步驟S410,將步驟S408所取得子節(jié)點(diǎn)標(biāo)識為已訪問,跳轉(zhuǎn)至步驟S402。
[0064]步驟S411,訪問完子節(jié)點(diǎn)后,再次調(diào)用靜態(tài)檢測組件,進(jìn)行代碼檢查和度量,在檢查和度量過程中,通過訪問局部符號棧與全局符號樹獲取符號信息,通過訪問注釋表獲取注釋信息。具體的,以“WHERE條件中表達(dá)式是否存在隱式轉(zhuǎn)換”檢查為例,當(dāng)節(jié)點(diǎn)傳遞給該檢查組件時,該檢查組件會判斷該節(jié)點(diǎn)是否是WHERE條件中的關(guān)系表達(dá)式,如果不是,則不進(jìn)行任何操作,如果是,則取表達(dá)式兩邊的符號,并從全局符號表和局部符號表中獲得兩邊符號的類型,如果類型不同,即可確認(rèn)存在隱式轉(zhuǎn)換。
[0065]步驟S412,判斷當(dāng)前節(jié)點(diǎn)是否表示新作用域,如果是,則跳轉(zhuǎn)至S413,否則跳轉(zhuǎn)至S415o
[0066]步驟S413,從局部符號棧中彈出符號表。
[0067]步驟S414,判斷節(jié)點(diǎn)棧是否為空,如果是,則表示語法樹遍歷結(jié)束,如果判斷節(jié)點(diǎn)棧不為空,跳轉(zhuǎn)至步驟S415。
[0068]步驟S415,從節(jié)點(diǎn)棧中取出一個節(jié)點(diǎn),并賦給當(dāng)前節(jié)點(diǎn),跳轉(zhuǎn)至步驟S402。
[0069]基于同一發(fā)明構(gòu)思,本發(fā)明實(shí)施例中還提供了一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測系統(tǒng),如下面的實(shí)施例所述。由于該系統(tǒng)解決問題的原理與上述方法相似,因此該系統(tǒng)的實(shí)施可以參見上述方法的實(shí)施,重復(fù)之處不再贅述。以下所使用的,術(shù)語“單元”或者“模塊”可以實(shí)現(xiàn)預(yù)定功能的軟件和/或硬件的組合。盡管以下實(shí)施例所描述的系統(tǒng)較佳地以軟件來實(shí)現(xiàn),但是硬件,或者軟件和硬件的組合的實(shí)現(xiàn)也是可能并被構(gòu)想的。
[0070]結(jié)合圖4所示,為本發(fā)明一實(shí)施例的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測系統(tǒng)結(jié)構(gòu)示意圖。該系統(tǒng)包括:
[0071]數(shù)據(jù)庫訪問單元I,用于建立與數(shù)據(jù)庫字典服務(wù)器6的連接,并還可以為代碼解析單元3提供數(shù)據(jù)庫字典信息,數(shù)據(jù)字典內(nèi)容包括存儲過程對象、存儲過程代碼、存儲過程引用的模式對象、模式對象信息等。
[0072]查詢單元2,用于查詢數(shù)據(jù)庫字典表,獲取當(dāng)前數(shù)據(jù)庫用戶下的所有存儲過程對象,并構(gòu)建成為待檢測對象列表。
[0073]代碼解析單元3,用于通過數(shù)據(jù)訪問單元I獲取數(shù)據(jù)庫用戶下存儲過程對象,包括程序包、獨(dú)立存儲過程、獨(dú)立函數(shù)等。判斷待檢測對象列表中是否存在未檢測的對象,如果有則對未檢測的對象的存儲過程進(jìn)行代碼解析,通過詞法分析、語法分析技術(shù)生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹。
[0074]代碼檢測單元4,用于根據(jù)生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果。
[0075]報(bào)告生成單元5,用于根據(jù)靜態(tài)檢測結(jié)果生成靜態(tài)檢測報(bào)告。
[0076]在本實(shí)施例中,結(jié)合圖5所示,為代碼解析單元的結(jié)構(gòu)示意圖。如圖5所示,代碼解析單元3包括:詞法分析組件31、語法分析組件32、注釋管理組件33和全局符號管理組件34;其中,
[0077]詞法分析組件31,用于對輸入的代碼字符流進(jìn)行逐個掃描,從字符中識別出標(biāo)識符、關(guān)鍵字、常量等相對獨(dú)立的記號(Token),形成記號流。
[0078]語法分析組件32,用于在詞法分析組件31輸出的記號流基礎(chǔ)上將獨(dú)立的記號根據(jù)語法文法組建為抽象語法樹。
[0079]注釋管理組件33,用于利用詞法分析組件31輸出的記號流,構(gòu)造注釋表,記錄每一段注釋的起始、結(jié)束位置和注釋內(nèi)容。
[0080]全局符號管理組件34,用于通過分析存儲過程所引用的對象,利用數(shù)據(jù)庫字典和代碼解析,獲取符號的類別、數(shù)據(jù)類型等信息。符號表由同屬于某作用域的符號或者同屬于某對象的符號組織,符號表再按照從屬關(guān)系組織成全局符號樹。以存表為例,表的模式符號存放在根符號表中,表符號存放在一級符號表中,該符號表是模式符號的子符號表,字段符號存放在二級符號表,該符號表;^表符號的子符號表。
[0081]在本實(shí)施例中,結(jié)合圖6所示,為代碼檢測單元的結(jié)構(gòu)示意圖。如圖6所示,代碼檢測單元4包括:局部符號管理組件41和靜態(tài)檢測組件42;其中,
[0082]局部符號管理組件41,用于負(fù)責(zé)管理局部符號桟,包括符號表入桟、符號表出桟、在棧頂符號表中添加符號;在抽象語法樹遍歷時,根據(jù)語義獲取符號信息,包括符號的類另IJ、數(shù)據(jù)類型,屬于相同作用域的符號組織成局部符號表;其中,局部符號只從存儲過程代碼中獲取,不會從數(shù)據(jù)庫字典獲取。
[0083]靜態(tài)檢測組件42,是一系列檢查組件和度量組件的集合,用于完成實(shí)際靜態(tài)測試任務(wù);檢查組件用于是檢查存儲過程是否存在缺陷或隱患,度量組件用于對存儲過程的整體質(zhì)量進(jìn)行評估。比如WHERE條件中表達(dá)式是否存在隱式轉(zhuǎn)換、游標(biāo)顯式打開后是否關(guān)閉等,而度量組件主要對存儲過程的整體質(zhì)量進(jìn)行評估,比如圈復(fù)雜度、有效代碼行數(shù)、存儲過程調(diào)用深度等。代碼檢測單元4對語法樹遍歷時,會在遍歷每個節(jié)點(diǎn)之前和之后都通知每個靜態(tài)檢測組件,每個組件根據(jù)自身需要,記錄有用的節(jié)點(diǎn)信息,進(jìn)行代碼檢查或度量。
[0084]本發(fā)明針對數(shù)據(jù)庫特點(diǎn),提出了一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法及系統(tǒng),相對于目前其他相關(guān)技術(shù),其突出優(yōu)點(diǎn)和有益效果是:
[0085]1、只需數(shù)據(jù)庫的連接信息和數(shù)據(jù)庫字典表的訪問權(quán)限即可完成存儲過程靜態(tài)檢測,改變現(xiàn)有靜態(tài)檢測方法對于代碼文件的依賴;
[0086]2、數(shù)據(jù)字典包含的儲過程代碼、表、視圖、類型等信息更加準(zhǔn)確和完整,這使得靜態(tài)檢測能力更加強(qiáng)大,可檢測WHERE條件中的隱式轉(zhuǎn)換、判斷SELECT INTO語句是否存在字符串長度溢出風(fēng)險(xiǎn)等;
[0087]3、對數(shù)據(jù)庫無限制,可支持目前所有的數(shù)據(jù)庫存儲過程,并具備對新的數(shù)據(jù)庫存儲過程的擴(kuò)充能力;
[0088]4、代碼與注釋的分離解析,既簡化了語法分析過程,又保留了代碼的完整信息,有利于針對注釋的靜態(tài)檢測組件的開發(fā);
[0089]5、主系統(tǒng)已解析出存儲過程所有信息,包括抽象語法樹、注釋庫與符號表,為復(fù)雜靜態(tài)檢測功能提供有效支持。
[0090]以上所述的具體實(shí)施例,對本發(fā)明的目的、技術(shù)方案和有益效果進(jìn)行了進(jìn)一步詳細(xì)說明,所應(yīng)理解的是,以上所述僅為本發(fā)明的具體實(shí)施例而已,并不用于限定本發(fā)明的保護(hù)范圍,凡在本發(fā)明的精神和原則之內(nèi),所做的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。
【主權(quán)項(xiàng)】
1.一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法,其特征在于,該方法包括: 步驟I,建立與數(shù)據(jù)庫字典服務(wù)器的連接; 步驟2,查詢數(shù)據(jù)庫字典表,獲取當(dāng)前數(shù)據(jù)庫用戶下的所有存儲過程對象,并構(gòu)建成為待檢測對象列表; 步驟3,判斷待檢測對象列表中是否存在未檢測的對象,如果存在則對未檢測的對象的存儲過程進(jìn)行代碼解析,生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹;步驟4,根據(jù)步驟3生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果; 步驟5,根據(jù)靜態(tài)檢測結(jié)果生成靜態(tài)檢測報(bào)告。2.根據(jù)權(quán)利要求1所述的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法,其特征在于,在步驟2中,存儲過程對象包括:程序包、獨(dú)立存儲過程、獨(dú)立函數(shù)、表結(jié)構(gòu)、自定義類型。3.根據(jù)權(quán)利要求1所述的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法,其特征在于,在步驟3中,判斷待檢測對象列表中是否存在未檢測的對象,如果有則對未檢測的對象的存儲過程進(jìn)行代碼解析,生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹,包括: 步驟301,判斷待檢測對象列表中是否存在未檢測的對象,如果有則進(jìn)入步驟302,如果沒有進(jìn)入步驟308; 步驟302,根據(jù)未檢測對象的對象類型,判斷未檢測對象的對象信息是否在數(shù)據(jù)庫字典中,如果是則跳轉(zhuǎn)至步驟307,否則跳轉(zhuǎn)至步驟303; 步驟303,從數(shù)據(jù)庫字典中獲取引用對象的代碼; 步驟304,使用詞法分析組件對引用對象的代碼進(jìn)行詞法分析,獲取記號流; 步驟305,使用語法分析組件分析記號流生成語法樹; 步驟306,遍歷語法樹,將代碼中的聲明提取為符號,將符號添加至全局符號樹中,跳轉(zhuǎn)至步驟301; 步驟307,從數(shù)據(jù)庫字典表中直接獲取對象信息,將對象信息添加至全局符號樹中,跳轉(zhuǎn)至步驟301; 步驟308,從數(shù)據(jù)庫字典中獲取存儲過程對象的代碼; 步驟309,對存儲過程對象的代碼進(jìn)行詞法分析,形成存儲過程對象的記號流; 步驟310,對存儲過程對象的記號流進(jìn)行注釋分析,獲得注釋表; 步驟311,對存儲過程對象的記號流進(jìn)行語法分析,生成語法樹。4.根據(jù)權(quán)利要求1所述的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法,其特征在于,在步驟4中,根據(jù)步驟3生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果,包括: 步驟401,將當(dāng)前節(jié)點(diǎn)設(shè)置為根節(jié)點(diǎn); 步驟402,判斷當(dāng)前節(jié)點(diǎn)是否表示新作用域,如果是新作用域則跳轉(zhuǎn)至步驟403,否則跳轉(zhuǎn)至步驟404; 步驟403,將新的空符號表通過局部符號管理組件壓入局部符號棧中; 步驟404,判斷當(dāng)前節(jié)點(diǎn)是不是新符號,如果是新符號則跳轉(zhuǎn)至步驟405,否則跳轉(zhuǎn)至步驟406; 步驟405,將符號添加至局部符號堆棧中; 步驟406,調(diào)用靜態(tài)檢測組件,進(jìn)行靜態(tài)檢測預(yù)處理,進(jìn)行變量使用前必須賦值的檢查時,標(biāo)識變量符號被初始化狀態(tài); 步驟407,判斷是否還存在未訪問的子節(jié)點(diǎn),如果是,則跳轉(zhuǎn)至步驟408,否則,跳轉(zhuǎn)至步驟411; 步驟408,將當(dāng)前節(jié)點(diǎn)壓入節(jié)點(diǎn)棧中; 步驟409,將當(dāng)前節(jié)點(diǎn)設(shè)為最左的未訪問子節(jié)點(diǎn); 步驟410,將步驟408所取得子節(jié)點(diǎn)標(biāo)識為已訪問,跳轉(zhuǎn)至步驟402; 步驟411,訪問完子節(jié)點(diǎn)后,再次調(diào)用靜態(tài)檢測組件,進(jìn)行代碼檢查和度量,在檢查和度量過程中,通過訪問局部符號棧與全局符號樹獲取符號信息,通過訪問注釋表獲取注釋信息; 步驟412,判斷當(dāng)前節(jié)點(diǎn)是否表示新作用域,如果是,則跳轉(zhuǎn)至413,否則跳轉(zhuǎn)至415; 步驟413,從局部符號桟中彈出符號表; 步驟414,判斷節(jié)點(diǎn)棧是否為空,如果是,則表示語法樹遍歷結(jié)束。5.根據(jù)權(quán)利要求4所述的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法,其特征在于,在步驟414中,如果判斷節(jié)點(diǎn)棧不為空,跳轉(zhuǎn)至步驟415; 步驟415,從節(jié)點(diǎn)棧中取出一個節(jié)點(diǎn),并賦給當(dāng)前節(jié)點(diǎn),跳轉(zhuǎn)至步驟402。6.根據(jù)權(quán)利要求4所述的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法,其特征在于,在步驟402中的新作用域產(chǎn)生于存儲過程的起始位置、SQL語句的起始位置。7.根據(jù)權(quán)利要求4所述的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測方法,其特征在于,在步驟404中的新符號產(chǎn)生于存儲過程定義、變量定義、類型定義。8.一種基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測系統(tǒng),其特征在于,該系統(tǒng)包括: 數(shù)據(jù)庫訪問單元,用于建立與數(shù)據(jù)庫字典服務(wù)器的連接; 查詢單元,用于查詢數(shù)據(jù)庫字典表,獲取當(dāng)前數(shù)據(jù)庫用戶下的所有存儲過程對象,并構(gòu)建成為待檢測對象列表; 代碼解析單元,用于判斷待檢測對象列表中是否存在未檢測的對象,如果有則對未檢測的對象的存儲過程進(jìn)行代碼解析,生成語法樹、注釋表,并將該未檢測的對象添加至全局符號樹; 代碼檢測單元,用于根據(jù)生成的語法樹、注釋表及全局符號樹,在抽象語法樹遍歷過程中生成局部符號棧以及調(diào)用靜態(tài)檢測組件,并對未檢測的對象的存儲過程進(jìn)行靜態(tài)檢測,獲得靜態(tài)檢測結(jié)果; 報(bào)告生成單元,用于根據(jù)靜態(tài)檢測結(jié)果生成靜態(tài)檢測報(bào)告。9.根據(jù)權(quán)利要求8所述的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測系統(tǒng),其特征在于,所述代碼解析單元包括:詞法分析組件、語法分析組件、注釋管理組件和全局符號管理組件;其中, 詞法分析組件,用于對輸入的代碼字符流進(jìn)行逐個掃描,從字符中識別出標(biāo)識符、關(guān)鍵字、常量等相對獨(dú)立的記號,形成記號流; 語法分析組件,用于在詞法分析組件輸出的記號流基礎(chǔ)上將獨(dú)立的記號根據(jù)語法文法組建為抽象語法樹; 注釋管理組件,用于利用詞法分析組件輸出的記號流,構(gòu)造注釋表,記錄每一段注釋的起始、結(jié)束位置和注釋內(nèi)容; 全局符號管理組件,用于通過分析存儲過程所引用的對象,利用數(shù)據(jù)庫字典和代碼解析,獲取符號的類別、數(shù)據(jù)類型等信息。10.根據(jù)權(quán)利要求8所述的基于數(shù)據(jù)庫字典的存儲過程靜態(tài)檢測系統(tǒng),其特征在于,代碼檢測單元包括:局部符號管理組件和靜態(tài)檢測組件;其中, 局部符號管理組件,用于負(fù)責(zé)管理局部符號桟,包括符號表入桟、符號表出桟、在桟頂符號表中添加符號;在抽象語法樹遍歷時,根據(jù)語義獲取符號信息,包括符號的類別、數(shù)據(jù)類型,屬于相同作用域的符號組織成局部符號表; 靜態(tài)檢測組件,是一系列檢查組件和度量組件的集合,用于完成實(shí)際靜態(tài)測試任務(wù);檢查組件用于是檢查存儲過程是否存在缺陷或隱患,度量組件用于對存儲過程的整體質(zhì)量進(jìn)行評估。
【文檔編號】G06F11/36GK105930267SQ201610237087
【公開日】2016年9月7日
【申請日】2016年4月15日
【發(fā)明人】魏亞東, 何正平, 姚辰, 許振峰
【申請人】中國工商銀行股份有限公司