Strange DupeString AV

Hi, I've made some Office 2003 - like color pickers (hexagon & hsl) and integrated them in a dialog component, now I'm making another dialog for my html-editor app. In this dialog users can manually enter hex color values. Here's the function I use to format (fix) the entered text so it can be properly converted from an html color value to a TColor value:

function TMoreColorsWin.FormatHTMLColor(S: string): string;

procedure ReplaceWrongChars(var s: string);
var
 i: integer;
begin
if s <> '' then
 for i := 1 to 6 do
  if not (s[i] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']) then
   s[i] := '0';
end;

var
 c: string;
begin
 c := '';
 if s <> '' then
  begin
   c := AnsiReplaceText(s, '#', '');
   ReplaceWrongChars(c);
   if Length(c) = 6 then
    Result := c
   else
    begin
     if Length(c) > 6 then
      c := Copy(c, 1, 6);
     if Length(c) < 6 then
      c := DupeString('0', 6 - Length(c)) + c;  //AV here!!!
     Result := c;
    end;
  end
 else
  Result := '000000';
end;

Everything works fine while "s" is more than 3 chars long, if it's length is 1, 2, 3 (eg "A") i get an AV. Here's how I use the function above :

(ENew: TEdit, NewSwatch - something like TShape)

procedure TMoreColorsWin.ENewKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
 s: string;
begin
if (Key = VK_RETURN) and ENew.Focused then
 begin
  s := FormatHTMLColor(ENew.Text);
  ENew.Text := s;
  NewSwatch.Color := HexToTColor(s);
 end;
end;

I've tried everything and I just can't get rid of the AV, what should I do???
BindzaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DragonSlayerCommented:
Don't know what DupeString is, heh, but I guess you could replace it with something like:

while Length(c) < 6 do
  c := '0' + c;

also, ReplaceWrongChars could be rewritten as follows (for brevity)

procedure ReplaceWrongChars(var s: string);
var
 i: integer;
begin
if s <> '' then
 for i := 1 to 6 do
  if not (s[i] in ['0' .. '9', 'A' .. 'F']) then
   s[i] := '0';
end;
0
rbohacCommented:
Intereting, I can't get this to duplicate.
0
rbohacCommented:
DupeString is contained in StrUtils
0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

rbohacCommented:
You haven't changed the DupeString function at all, have you?
0
Pierre CorneliusCommented:
Instead of this:

  if Length(c) < 6 then
      c := DupeString('0', 6 - Length(c)) + c;  //AV here!!!

try this:

While Length(c) < 6 do c:= '0'+c;

regards
Pierre
0
Pierre CorneliusCommented:
The reason for your Access violation is in your ReplaceWrongChars function. You iterate for i:= 1 to 6 in your function therefore if the string parameter you pass to the function is anything less than 6 you will get an AV because you are trying to access e.g. s[4] when only up to s[3] was allocated memory for.

Try this:

function FormatHTMLColor(S: string): string;
var i: integer;
begin
  result:= StringReplace(s, '#','', [rfReplaceAll]);

  if Length(s) > 6
    then SetLength(result, 6)
    else while length(result) < 6 do result:= '0'+result;

  //by now you can be sure the result string is 6 chars long so
  //iterating from 1 to 6 shouldn't give you any AV's
  for i := 1 to 6 do
    if not (result[i] in ['0'..'9', 'A'..'F'])
      then result[i] := '0';
end;

Regards
Pierre
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Pierre CorneliusCommented:
sorry, second line should be

  "if Length(result) > 6"  INSTEAD OF "if Length(s) > 6"

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.