#1 Re: Other components » SynCommons.pas and UpperCopy255Buf() oddities » 2016-01-13 21:11:17

Based on most of the places this function is used it might make sense that is intended for small text, but then there are functions such as HashAnsiStringI() where this might not be clear at all.

So assuming the result doesn't need to be null terminated is it safe to assume that for consistent results the source should be 240 characters or less?

#2 Other components » SynCommons.pas and UpperCopy255Buf() oddities » 2016-01-13 20:24:54

bigstar
Replies: 2

First a minor documentation problem, the comments below state that 256 chars are copied into the dest buffer, but dest is actually limited to much less space; how much less depends on whether UpperCopy255BufPas() or UpperCopy255BufSSE42() is used

/// copy source^ into a 256 chars dest^ buffer with 7 bits upper case conversion
// - this version is written in optimized pascal
// - you should not have to call this function, but rely on UpperCopy255Buf()
// - returns final dest pointer
// - will copy up to 255 AnsiChar (expect the dest buffer to be defined e.g. as
// array[byte] of AnsiChar on the caller stack)

I found that passing a string of HelloWord repeated 26 times (260 characters total) to:

UpperCopy255BufPas() is truncated to 252 characters, with the last 4 bytes containing random bytes because the tmp buffer is not zeroed out before use and the result is not null terminated

UpperCopy255BufSSE42() appears to truncate to 240 characters, with the last 16 bytes containing random bytes

I noticed the following routines within SynCommons.pas do something like

  UpperCopy255(Up,aStartName)^ := #0;

or

  PWord(UpperCopy255(UpperSection,SectionName))^ := ord(']');

If the source is 'hello' and length is 5 and we do something like this

     UpperCopy255BufPas(tmp, pUTF8Char(S), Len )^ := #0;
or
     UpperCopy255BufSSE42(tmp, pUTF8Char(S), Len )^ := #0;

we get the same result HELLO#0

but now if the source is HelloWord repeated 26 times and we call the code above the results are different

HELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWOR#0<followed by random bytes>

HELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORLDHELLOWORL#0<followed by random bytes>

Is this the intended behavior? If so I think it should be documented somewhere.

Also there is no way to determine the exact length of the result.

#3 Re: Other components » Possible bug in SynCommons.pas TRawUTF8List.BeginUpdate; » 2014-12-18 17:23:57

Take a look at this quick demo to illustrate the bug

var
    Counter: Integer = 0;

procedure TForm1.DoOnChange(Sender: TObject);
begin
     Counter := Counter + 1;
     Form1.Caption := IntToStr(Counter);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
   list: TRawUTF8List;
begin
     Counter := 0;
     list := TRawUTF8List.Create(false);

     list.OnChange := Form1.DoOnChange;

     list.BeginUpdate;
     list.Add('1');
     list.Add('2');
     list.Add('3');
     list.Add('4');
     list.EndUpdate;

     list.Free;
end;

How many times do you think DoOnChange() is triggered? It's not 1 but 4 times, one for each .Add()

I corrected the problem by changing the evaluation from >0 to >1 as shown below, not sure if this is the appropriate fix, if anything maybe a comment is needed.

procedure TRawUTF8List.BeginUpdate;
begin
  inc(fOnChangeLevel);
  if fOnChangeLevel>1 then
    exit;
  fOnChangeHidden := fOnChange;
  fOnChange := OnChangeHidden;
  fOnChangeTrigerred := false;
end;

#4 Other components » Possible bug in SynCommons.pas TRawUTF8List.BeginUpdate; » 2014-12-18 16:05:44

bigstar
Replies: 3

Hello,

While experimenting with TRawUTF8List I noticed that BeginUpdate/EndUpdate didn't work as expected.

Upon reviewing the code the logic seems flawed.

procedure TRawUTF8List.BeginUpdate;
begin
  inc(fOnChangeLevel);
  if fOnChangeLevel>0 then
    exit;
  fOnChangeHidden := fOnChange;
  fOnChange := OnChangeHidden;
  fOnChangeTrigerred := false;
end;

The first call to BeginUpdate will increase fOnChangeLevel from 0 to 1 and the next line evaluates if fOnChangeLevel > 0 then exit. The last 3 lines will never be executed.

#5 Other components » SynMemoEx.pas TMemoEX minor bug » 2014-01-31 15:33:25

bigstar
Replies: 1

The default value for the CursorBeyondEOL property is defined as false but within the TMemoEx constructor the value is initialized to true.

Board footer

Powered by FluxBB