[Delphi 2009 BUG] StrToIntDef('丸', 0) = 8

来源:互联网 发布:java高级编程 编辑:程序博客网 时间:2024/06/12 01:10
如果你StrToIntDef('丸子', 0),必然返回0,而一个字符的‘丸’,却返回8。 
跟踪之后,发现竟然用这样的代码去处理UniCode字符串,而‘丸’的UniCode编码是 $38 $4E,很搞笑吧。 

  1.         MOV     BL,[ESI] 
  2.         {$IFNDEF UNICODE} 
  3.         INC     ESI 
  4.         {$ELSE
  5.         ADD     ESI, 2 
  6.         {$ENDIF
  7.         CMP     BL,' ' 
  8.         JE      @@blankLoop 
System.Pas Line 7532,完整代码如下: 

  1. function _ValLong(const s: stringvar code: Integer): Longint;
  2. {$IFDEF PUREPASCAL}
  3. var
  4.   I, Len: Integer;
  5.   Negative, Hex: Boolean;
  6. begin
  7.   // U-OK
  8.   I := 1;
  9.   code := -1;
  10.   Result := 0;
  11.   Negative := False;
  12.   Hex := False;
  13.   Len := Length(s);
  14.   while (I <= Len) and (s[I] = ' 'do Inc(I);
  15.   if I > Len then Exit;
  16.   case s[I] of
  17.     '$',
  18.     'x',
  19.     'X'begin
  20.           Hex := True;
  21.           Inc(I);
  22.          end;
  23.     '0'begin
  24.           Hex := (Len > I) and (UpCase(s[I+1]) = 'X');
  25.     if Hex then Inc(I,2);
  26.          end;
  27.     '-'begin
  28.           Negative := True;
  29.           Inc(I);
  30.          end;
  31.     '+': Inc(I);
  32.   end;
  33.   if Hex then
  34.     while I <= Len do
  35.     begin
  36.       if Result > (High(Result) div 16then
  37.       begin
  38.         code := I;
  39.         Exit;
  40.       end;
  41.       case s[I] of
  42.         '0'..'9': Result := Result * 16 + Ord(s[I]) - Ord('0');
  43.         'a'..'f': Result := Result * 16 + Ord(s[I]) - Ord('a') + 10;
  44.         'A'..'F': Result := Result * 16 + Ord(s[I]) - Ord('A') + 10;
  45.       else
  46.         code := I;
  47.         Exit;
  48.       end;
  49.     end
  50.   else
  51.     while I <= Len do
  52.     begin
  53.       if Result > (High(Result) div 10then
  54.       begin
  55.         code := I;
  56.         Exit;
  57.       end;
  58.       Result := Result * 10 + Ord(s[I]) - Ord('0');
  59.       Inc(I);
  60.     end;
  61.   if Negative then
  62.     Result := -Result;
  63.   code := 0;
  64. end;
  65. {$ELSE}
  66. asm
  67. {       FUNCTION _ValLong( s: string; VAR code: Integer ) : Longint;        }
  68. {     ->EAX     Pointer to string       }
  69. {       EDX     Pointer to code result  }
  70. {     <-EAX     Result          }
  71.         PUSH    EBX
  72.         PUSH    ESI
  73.         PUSH    EDI
  74.         MOV     ESI,EAX
  75.         PUSH    EAX          { save for the error case       }
  76.         TEST    EAX,EAX
  77.         JE      @@empty
  78.         XOR     EAX,EAX
  79.         XOR     EBX,EBX
  80.         MOV     EDI,07FFFFFFFH / 10     { limit }
  81. @@blankLoop:
  82.         MOV     BL,[ESI]
  83.         {$IFNDEF UNICODE}
  84.         INC     ESI
  85.         {$ELSE}
  86.         ADD     ESI, 2
  87.         {$ENDIF}
  88.         CMP     BL,' '
  89.         JE      @@blankLoop
  90. @@endBlanks:
  91.         MOV     CH,0
  92.         CMP     BL,'-'
  93.         JE      @@minus
  94.         CMP     BL,'+'
  95.         JE      @@plus
  96. @@checkDollar:
  97.         CMP     BL,'$'
  98.         JE      @@dollar
  99.         CMP     BL, 'x'
  100.         JE      @@dollar
  101.         CMP     BL, 'X'
  102.         JE      @@dollar
  103.         CMP     BL, '0'
  104.         JNE     @@firstDigit
  105.         MOV     BL, [ESI]
  106.         {$IFNDEF UNICODE}
  107.         INC     ESI
  108.         {$ELSE}
  109.         ADD     ESI, 2
  110.         {$ENDIF}
  111.         CMP     BL, 'x'
  112.         JE      @@dollar
  113.         CMP     BL, 'X'
  114.         JE      @@dollar
  115.         TEST    BL, BL
  116.         JE      @@endDigits
  117.         JMP     @@digLoop
  118. @@firstDigit:
  119.         TEST    BL,BL
  120.         JE      @@error
  121. @@digLoop:
  122.         SUB     BL,'0'
  123.         CMP     BL,9
  124.         JA      @@error
  125.         CMP     EAX,EDI         { value > limit ?       }
  126.         JA      @@overFlow
  127.         LEA     EAX,[EAX+EAX*4]
  128.         ADD     EAX,EAX
  129.         ADD     EAX,EBX         { fortunately, we can't have a carry    }
  130.         MOV     BL,[ESI]
  131.         {$IFNDEF UNICODE}
  132.         INC     ESI
  133.         {$ELSE}
  134.         ADD     ESI, 2
  135.         {$ENDIF}
  136.         TEST    BL,BL
  137.         JNE     @@digLoop
  138. @@endDigits:
  139.         DEC     CH
  140.         JE      @@negate
  141.         TEST    EAX,EAX
  142.         JGE     @@successExit
  143.         JMP     @@overFlow
  144. @@empty:
  145.         {$IFNDEF UNICODE}
  146.         INC     ESI
  147.         {$ELSE}
  148.         ADD     ESI, 2
  149.         {$ENDIF}
  150.         JMP     @@error
  151. @@negate:
  152.         NEG     EAX
  153.         JLE     @@successExit
  154.         JS      @@successExit          { to handle 2**31 correctly, where the negate overflows }
  155. @@error:
  156. @@overFlow:
  157.         POP     EBX
  158.         SUB     ESI,EBX
  159.         JMP     @@exit
  160. @@minus:
  161.         INC     CH
  162. @@plus:
  163.         MOV     BL,[ESI]
  164.         {$IFNDEF UNICODE}
  165.         INC     ESI
  166.         {$ELSE}
  167.         ADD     ESI, 2
  168.         {$ENDIF}
  169.         JMP     @@checkDollar
  170. @@dollar:
  171.         MOV     EDI,0FFFFFFFH
  172.         MOV     BL,[ESI]
  173.         {$IFNDEF UNICODE}
  174.         INC     ESI
  175.         {$ELSE}
  176.         ADD     ESI, 2
  177.         {$ENDIF}
  178.         TEST    BL,BL
  179.         JZ      @@empty
  180. @@hDigLoop:
  181.         CMP     BL,'a'
  182.         JB      @@upper
  183.         SUB     BL,'a' - 'A'
  184. @@upper:
  185.         SUB     BL,'0'
  186.         CMP     BL,9
  187.         JBE     @@digOk
  188.         SUB     BL,'A' - '0'
  189.         CMP     BL,5
  190.         JA      @@error
  191.         ADD     BL,10
  192. @@digOk:
  193.         CMP     EAX,EDI
  194.         JA      @@overFlow
  195.         SHL     EAX,4
  196.         ADD     EAX,EBX
  197.         MOV     BL,[ESI]
  198.         {$IFNDEF UNICODE}
  199.         INC     ESI
  200.         {$ELSE}
  201.         ADD     ESI, 2
  202.         {$ENDIF}
  203.         TEST    BL,BL
  204.         JNE     @@hDigLoop
  205.         DEC     CH
  206.         JNE     @@successExit
  207.         NEG     EAX
  208. @@successExit:
  209.         POP     ECX          { saved copy of string pointer  }
  210.         XOR     ESI,ESI         { signal no error to caller     }
  211. @@exit:
  212.         {$IFDEF UNICODE}
  213.         SHR     ESI, 1
  214.         {$ENDIF}
  215.         MOV     [EDX],ESI
  216.         POP     EDI
  217.         POP     ESI
  218.         POP     EBX
  219. end;
  220. {$ENDIF}
 
原创粉丝点击