Linux-Bulgaria.ORG
навигация

 

начало

пощенски списък

архив на групата

семинари ...

документи

как да ...

 

 

Предишно писмо Следващо писмо Предишно по тема Следващо по тема По Дата По тема (thread)

Re: lug-bg: Linux normal path


  • Subject: Re: lug-bg: Linux normal path
  • From: Peter Pentchev <roam@xxxxxxxxxxx>
  • Date: Wed, 24 Nov 2004 12:48:03 +0200

On Wed, Nov 24, 2004 at 11:49:37AM +0200, Aleksandar Valchev wrote:
> Трябва ми една функция на C++, която от зададения като стринг път да го 
> нормализира т.е. от ///home////blabla/// -> /home/blabla. 
> 
> Някой да се сеща за други преобразования?

Ако искаш бърз отговор - не е толкова просто...  Погледни какво съм
написал за APR (Apache Portable Runtime) в последния параграф, но след
това - а за предпочитане преди това - може да прочетеш и другите неща,
които написах :)

Зависи каква точно ти е целта :)  Откъде идва този път, накъде ще отива,
през какви преобразувания ще минава след това...

Основните проблеми са три:
- escape-ване на отделни символи с \
- quote-ване на по-големи поредици символи с ' или "
- интересни неща като /../

Първите две са на практика едно и също, ще ги разгледаме заедно.

Въпросът е 1. дали някой ти е подал нещата, escape-нати или quote-нати
по този начин, и 2. дали ти трябва да ги подадеш на този след теб,
escape-нати или quote-нати по този начин.

Как са ти ги подали...  Ако parse-ваш директно user input, или си играеш
на нещо като шел или нещо такова, може да се наложи да преобразуваш
пътя, преди да му правиш проверки за коректност и каноникализация.  В
смисъл, може да се наложи да се разходиш по него символ по символ, при
срещане на \ да сложиш следващия символ директно, при срещане на кавичка
или апостроф да вземеш всичко до следващата, такива неща.  Макар че в
общия случай това трябва да бъде решено още *преди* да ти подадат на теб
нещата - ако става дума за user input, вероятно още преди това си го
разбил на думи и в този момент си се справил с кавичките, апострофите и
quote-ването.  Ако не си, ще трябва да го направиш, преди да започнеш
каноникализация.

Да ги подадеш на този след теб...  Ако ще ги подаваш на chdir(2),
mkdir(2), opendir(2) или нещо такова, или като параметър на програма,
която изпълняваш *директно* с exec*(3) или Perl-овския вариант на exec()
СЪС СПИСЪК от параметри, тогава НЕ трябва да escape/quote-ваш нищо.  Ако
обаче ще си строиш команда, която да подадеш на шел или на system(3) (то
е горе-долу едно и също), или на Perl/PHP exec()/passthru() с ЕДИН
параметър (при което то също го подава на system(3)), или на glob(3) или
Perl-овски glob(), тогава трябва много да внимаваш с интервалите, да не
се окаже в един момент, че вместо един път подаваш три.  А, да, ако го
подаваш на нещо, което в един момент ще стигне до изпълнение от шел, ще
е добре да escape-неш *всички* символи, които не са букви, цифри, тирета
или подчертавки - така хем ще хванеш неща като точка и запетая, долар,
обратни апострофи и какво ли не, хем ще "хванеш" и неща, за които в
момента не е ясно, че значат нещо специално за шела, но в някой бъдещ
шел ще значат.

Ако ще ги слагаш в SQL заявки, там нещата също са по-специални, но и
правилата са малко по-различни... но ако си стигнал дотук, би трябвало
да ги знаеш - пак кавички, апострофи, тук-там по някоя обратна наклонена
черта, и си общо-взето готов.

Ако ще ги даваш на нещо трето, тогава пак ще трябва да се замислиш за
това как това трето нещо интерпретира различни поредици от символи -
примерно дали се опитва да разпознае %2E или &amp; или &#1031; или
някакъв друг вид представяне на multibyte characters, character entities
и какво ли не още.  За малък пример виж следващата точка :)

Сега за третата точка - зависи какво все пак ще правиш с този път и защо
го каноникализираш.  Ако целта ти е да ограничиш достъпа до дадено дърво
от директории, тогава определено ще трябва да внимаваш за /../, но - и
тук има едно голямо но - това внимаване за '..' *задължително* трябва да
бъде синхронизирано с преобразуването на пътя във вид, удобен за
логаритмуване от този *след* теб.  Като много бърза демонстрация виж
десетките начини, по които в продължение на 4-5 години различни
части от MS IIS можеха да бъдат излъгани да ти дадат достъп до различни
части от файловата система, защото това, което каноникализираше и
проверяваше, не винаги знаеше за всички възможности, по които следващият
можеше да интерпретира пътя - в един момент можеш да му подадеш /.%2e/ и
то ще мине, после пък се оказва, че може и с /..%00/, после пък можеше
да подадеш едната или двете точки като Unicode, после изведнъж мина нещо
като /..%2F и изобщо... тези две неща *трябва* да бъдат синхронизирани!

Ако ти се струва, че го правя да изглежда сложно, причината е съвсем
проста - каноникализация на пътища НАИСТИНА е много сложно нещо, и много
зависи от това от кого ги взимаш, на кого ги даваш, и с каква цел ги
каноникализираш.  Ако искаш просто решение, което ще работи в голяма
част от случаите, погледни Apache Portable Runtime (apr) -
http://apr.apache.org/ - страхотна библиотека от какви ли не функции,
която е в основата на факта, че Apache върви върху толкова много
платформи.  Там има секцийка 'Filepath Manipulation Functions' -
http://apr.apache.org/docs/apr/group__apr__filepath.html - някои от тях
може и да ти свършат работа :)

Поздрави,
Петър

-- 
Peter Pentchev	roam@xxxxxxxxxxx    roam@xxxxxxxx    roam@xxxxxxxxxxx
PGP key:	http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint	FDBA FD79 C26F 3C51 C95E  DF9E ED18 B68D 1619 4553
This inert sentence is my body, but my soul is alive, dancing in the sparks of your brain.

Attachment: pgpb24GZFX3jT.pgp
Description: PGP signature



 

наши приятели

 

линукс за българи
http://linux-bg.org

FSA-BG
http://fsa-bg.org

OpenFest
http://openfest.org

FreeBSD BG
http://bg-freebsd.org

KDE-BG
http://kde.fsa-bg.org/

Gnome-BG
http://gnome.cult.bg/

проект OpenFMI
http://openfmi.net

NetField Forum
http://netField.ludost.net/forum/

 

 

Linux-Bulgaria.ORG

Mailing list messages are © Copyright their authors.