From fbc017cdba81fa7b159bca5fd0b3a4fb4885c5ad Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Mon, 5 Mar 2012 22:22:10 +0100 Subject: [PATCH 01/11] added test blueprints, fixed? encoding issues --- tests/xss_filter_tests.php | 140 +++++++++++++++++++++++++++++++++++++ view/de/strings.php | 20 +++--- 2 files changed, 150 insertions(+), 10 deletions(-) create mode 100644 tests/xss_filter_tests.php diff --git a/tests/xss_filter_tests.php b/tests/xss_filter_tests.php new file mode 100644 index 0000000000..2d29e390a2 --- /dev/null +++ b/tests/xss_filter_tests.php @@ -0,0 +1,140 @@ +' + +$validstring=notags($invalidstring); +$escapedString=escape_tags($invalidstring); + +assert("[submit type="button" onclick="alert(\'failed!\');" /]", $validstring); +assert("what ever", $escapedString); + +/** +*autonames should be random, even length +*/ +$autoname1=autoname(10); +$autoname2=autoname(10); + +assertNotEquals($autoname1, $autoname2); + +/** +*autonames should be random, odd length +*/ +$autoname1=autoname(9); +$autoname2=autoname(9); + +assertNotEquals($autoname1, $autoname2); + +/** +* try to fail autonames +*/ +$autoname1=autoname(0); +$autoname2=autoname(MAX_VALUE); +$autoname3=autoname(1); +assert(count($autoname1), 0); +assert(count($autoname2), MAX_VALUE); +assert(count($autoname3), 1); + +/** +*xmlify and unxmlify +*/ +$text="I want to break\n this!11!" +$xml=xmlify($text); //test whether it actually may be part of a xml document +$retext=unxmlify($text); + +assert($text, $retext); + +/** +* test hex2bin and reverse +*/ + +assert(-3, hex2bin(bin2hex(-3))); +assert(0, hex2bin(bin2hex(0))); +assert(12, hex2bin(bin2hex(12))); +assert(MAX_INT, hex2bin(bin2hex(MAX_INT))); + +/** +* test expand_acl +*/ +$text="<1><2><3>"; +assert(array(1, 2, 3), $text); + +$text="<1><279012><15>"; +assert(array(1, 279012, 15), $text); + +$text="<1><279012>"; //maybe that's invalid +assert(array(1, 279012, "tt"), $text); + +$text="<1><279 012>"; //maybe that's invalid +assert(array(1, "279 012", "tt"), $text); + +$text=""; //maybe that's invalid +assert(array(), $text); + +$text="According to documentation, that's invalid. "; //should be invalid +assert(array(), $text); + +$text=" diff --git a/view/de/strings.php b/view/de/strings.php index 284c87f2fa..2d29f69e28 100755 --- a/view/de/strings.php +++ b/view/de/strings.php @@ -4,7 +4,7 @@ function string_plural_select_de($n){ return ($n != 1); } ; -$a->strings["Post successful."] = "Beitrag erfolgreich veröffentlicht."; +$a->strings["Post successful."] = "Beitrag erfolgreich veröffentlicht."; $a->strings["[Embedded content - reload page to view]"] = "[Eingebetteter Inhalt - Seite neu laden zum Betrachten]"; $a->strings["Contact settings applied."] = "Einstellungen zum Kontakt angewandt."; $a->strings["Contact update failed."] = "Konnte den Kontakt nicht aktualisieren."; @@ -12,15 +12,15 @@ $a->strings["Permission denied."] = "Zugriff verweigert."; $a->strings["Contact not found."] = "Kontakt nicht gefunden."; $a->strings["Repair Contact Settings"] = "Kontakt-Einstellungen reparieren"; $a->strings["WARNING: This is highly advanced and if you enter incorrect information your communications with this contact may stop working."] = "ACHTUNG: Das sind Experten-Einstellungen! Wenn Du etwas falsches eingibst, funktioniert die Kommunikation mit diesem Kontakt evtl. nicht mehr."; -$a->strings["Please use your browser 'Back' button now if you are uncertain what to do on this page."] = "Bitte nutze den Zurück-Button deines Browsers jetzt, wenn du dir unsicher bist, was auf dieser Seite gemacht wird."; -$a->strings["Return to contact editor"] = "Zurück zum Kontakteditor"; +$a->strings["Please use your browser 'Back' button now if you are uncertain what to do on this page."] = "Bitte nutze den Zurück-Button deines Browsers jetzt, wenn du dir unsicher bist, was auf dieser Seite gemacht wird."; +$a->strings["Return to contact editor"] = "Zurück zum Kontakteditor"; $a->strings["Name"] = "Name"; $a->strings["Account Nickname"] = "Account-Spitzname"; -$a->strings["@Tagname - overrides Name/Nickname"] = "@Tagname - überschreibt Name/Spitzname"; +$a->strings["@Tagname - overrides Name/Nickname"] = "@Tagname - überschreibt Name/Spitzname"; $a->strings["Account URL"] = "Account-URL"; -$a->strings["Friend Request URL"] = "URL für Freundschaftsanfragen"; -$a->strings["Friend Confirm URL"] = "URL für Bestätigungen von Freundschaftsanfragen"; -$a->strings["Notification Endpoint URL"] = "URL-Endpunkt für Benachrichtigungen"; +$a->strings["Friend Request URL"] = "URL für Freundschaftsanfragen"; +$a->strings["Friend Confirm URL"] = "URL für Bestätigungen von Freundschaftsanfragen"; +$a->strings["Notification Endpoint URL"] = "URL-Endpunkt für Benachrichtigungen"; $a->strings["Poll/Feed URL"] = "Pull/Feed-URL"; $a->strings["New photo from this URL"] = "Neues Foto von dieser URL"; $a->strings["Submit"] = "Senden"; @@ -28,7 +28,7 @@ $a->strings["Help:"] = "Hilfe:"; $a->strings["Help"] = "Hilfe"; $a->strings["Not Found"] = "Nicht gefunden"; $a->strings["Page not found."] = "Seite nicht gefunden."; -$a->strings["File exceeds size limit of %d"] = "Die Datei ist größer als das erlaubte Limit von %d"; +$a->strings["File exceeds size limit of %d"] = "Die Datei ist größer als das erlaubte Limit von %d"; $a->strings["File upload failed."] = "Hochladen der Datei fehlgeschlagen."; $a->strings["Friend suggestion sent."] = "Kontaktvorschlag gesendet."; $a->strings["Suggest Friends"] = "Kontakte vorschlagen"; @@ -40,7 +40,7 @@ $a->strings["link to source"] = "Link zum Originalbeitrag"; $a->strings["Events"] = "Veranstaltungen"; $a->strings["Create New Event"] = "Neue Veranstaltung erstellen"; $a->strings["Previous"] = "Vorherige"; -$a->strings["Next"] = "Nächste"; +$a->strings["Next"] = "Nächste"; $a->strings["hour:minute"] = "Stunde:Minute"; $a->strings["Event details"] = "Veranstaltungsdetails"; $a->strings["Format is %s %s. Starting date and Description are required."] = "Format ist %s %s. Anfangsdatum und Beschreibung sind notwendig."; @@ -643,7 +643,7 @@ $a->strings["Site name"] = "Seitenname"; $a->strings["Banner/Logo"] = "Banner/Logo"; $a->strings["System language"] = "Systemsprache"; $a->strings["System theme"] = "Systemweites Thema"; -$a->strings["Maximum image size"] = "Maximale Größe von Bildern"; +$a->strings["Maximum image size"] = "Maximale Größe von Bildern"; $a->strings["Register policy"] = "Registrierungsmethode"; $a->strings["Register text"] = "Registrierungstext"; $a->strings["Accounts abandoned after x days"] = "Accounts gelten nach x Tagen als unbenutzt"; From 185fcd0701946babf61066b49582225286061563 Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Thu, 8 Mar 2012 17:43:12 +0100 Subject: [PATCH 02/11] better tests --- build.xml | 52 ++++++++- tests/xss_filter_test.php | 217 +++++++++++++++++++++++++++++++++++++ tests/xss_filter_tests.php | 140 ------------------------ 3 files changed, 265 insertions(+), 144 deletions(-) create mode 100644 tests/xss_filter_test.php delete mode 100644 tests/xss_filter_tests.php diff --git a/build.xml b/build.xml index 83c5300264..0f57450726 100644 --- a/build.xml +++ b/build.xml @@ -1,14 +1,58 @@ - + + + set_include_path( + get_include_path() . PATH_SEPARATOR + . 'include' . PATH_SEPARATOR + . 'library' . PATH_SEPARATOR + . 'library/phpsec' . PATH_SEPARATOR + . '.' ); + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/xss_filter_test.php b/tests/xss_filter_test.php new file mode 100644 index 0000000000..e480ef7ec0 --- /dev/null +++ b/tests/xss_filter_test.php @@ -0,0 +1,217 @@ +'; + + $validstring=notags($invalidstring); + $escapedString=escape_tags($invalidstring); + + $this->assertEquals('[submit type="button" onclick="alert(\'failed!\');" /]', $validstring); + $this->assertEquals("<submit type="button" onclick="alert('failed!');" />", $escapedString); + } + + /** + *autonames should be random, even length + */ + public function testAutonameEven() { + $autoname1=autoname(10); + $autoname2=autoname(10); + + $this->assertNotEquals($autoname1, $autoname2); + } + + /** + *autonames should be random, odd length + */ + public function testAutonameOdd() { + $autoname1=autoname(9); + $autoname2=autoname(9); + + $this->assertNotEquals($autoname1, $autoname2); + } + + /** + * try to fail autonames + */ + public function testAutonameNoLength() { + $autoname1=autoname(0); + $this->assertEquals(0, count($autoname1)); + } + + public function testAutonameNegativeLength() { + $autoname1=autoname(-23); + $this->assertEquals(0, count($autoname1)); + } + +// public function testAutonameMaxLength() { +// $autoname2=autoname(PHP_INT_MAX); +// $this->assertEquals(PHP_INT_MAX, count($autoname2)); +// } + + public function testAutonameLength1() { + $autoname3=autoname(1); + $this->assertEquals(1, count($autoname3)); + } + + /** + *xmlify and unxmlify + */ + public function testXmlify() { + $text="I want to break\n this!11!"; + $xml=xmlify($text); //test whether it actually may be part of a xml document + $retext=unxmlify($text); + + $this->assertEquals($text, $retext); + } + + /** + * test hex2bin and reverse + */ + + public function testHex2Bin() { + $this->assertEquals(-3, hex2bin(bin2hex(-3))); + $this->assertEquals(0, hex2bin(bin2hex(0))); + $this->assertEquals(12, hex2bin(bin2hex(12))); + $this->assertEquals(PHP_INT_MAX, hex2bin(bin2hex(PHP_INT_MAX))); + } + + /** + * test expand_acl + */ + public function testExpandAclNormal() { + $text="<1><2><3>"; + $this->assertEquals(array(1, 2, 3), expand_acl($text)); + } + + public function testExpandAclBigNumber() { + $text="<1><279012><15>"; + $this->assertEquals(array(1, 279012, 15), expand_acl($text)); + } + + public function testExpandAclString() { + $text="<1><279012>"; //maybe that's invalid + $this->assertEquals(array(1, 279012, 'tt'), expand_acl($text)); + } + + public function testExpandAclSpace() { + $text="<1><279 012><32>"; //maybe that's invalid + $this->assertEquals(array(1, "279 012", "32"), expand_acl($text)); + } + + public function testExpandAclEmpty() { + $text=""; //maybe that's invalid + $this->assertEquals(array(), expand_acl($text)); + } + + public function testExpandAclNoBrackets() { + $text="According to documentation, that's invalid. "; //should be invalid + $this->assertEquals(array(), expand_acl($text)); + } + + public function testExpandAclJustOneBracket1() { + $text="assertEquals(array(), expand_acl($text)); + } + + public function testExpandAclJustOneBracket2() { + $text="Another invalid> string"; //should be invalid + $this->assertEquals(array(), expand_acl($text)); + } + + public function testExpandAclCloseOnly() { + $text="Another> invalid> string>"; //should be invalid + $this->assertEquals(array(), expand_acl($text)); + } + + public function testExpandAclOpenOnly() { + $text="assertEquals(array(), expand_acl($text)); + } + + public function testExpandAclNoMatching1() { + $text=" invalid "; //should be invalid + $this->assertEquals(array(), expand_acl($text)); + } + + public function testExpandAclNoMatching2() { + $text="<1>2><3>"; + $this->assertEquals(array(), expand_acl($text)); + } + + /** + * test attribute contains + */ + public function testAttributeContains1() { + $testAttr="class1 notclass2 class3"; + $this->assertTrue(attribute_contains($testAttr, "class3")); + $this->assertFalse(attribute_contains($testAttr, "class2")); + } + + /** + * test attribute contains + */ + public function testAttributeContains2() { + $testAttr="class1 not-class2 class3"; + $this->assertTrue(attribute_contains($testAttr, "class3")); + $this->assertFalse(attribute_contains($testAttr, "class2")); + } + + public function testAttributeContainsEmpty() { + $testAttr=""; + $this->assertFalse(attribute_contains($testAttr, "class2")); + } + + public function testAttributeContainsSpecialChars() { + $testAttr="--... %\$ä() /(=?}"; + $this->assertFalse(attribute_contains($testAttr, "class2")); + } + + /** + * test get_tags + */ + public function testGetTags() { + $text="hi @Mike, I'm just writing #test_cases, " + ." so @somebody@friendica.com may change #things. Of course I " + ."look for a lot of #pitfalls, like #tags at the end of a sentence " + ."@comment. I hope noone forgets about @fullstops.because that might" + ." break #things. @Mike@campino@friendica.eu is also #nice, isn't it? " + ."Now, add a @first_last tag. "; + //check whether this are all variants (no, auto-stuff is missing). + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("#test_cases", $tags[1]); + $this->assertEquals("@somebody@friendica.com", $tags[2]); + $this->assertEquals("#things", $tags[3]); + $this->assertEquals("#pitfalls", $tags[4]); + $this->assertEquals("#tags", $tags[5]); + $this->assertEquals("@comment", $tags[6]); + $this->assertEquals("@fullstops", $tags[7]); + $this->assertEquals("#things", $tags[8]); + $this->assertEquals("@Mike", $tags[9]); + $this->assertEquals("@campino@friendica.eu", $tags[10]); + $this->assertEquals("#nice", $tags[11]); + $this->assertEquals("@first_last", $tags[12]); + } + + public function testGetTagsEmpty() { + $tags=get_tags(""); + $this->assertEquals(0, count($tags)); + } +//function qp, quick and dirty?? +//get_mentions +//get_contact_block, bis Zeile 538 +} +?> diff --git a/tests/xss_filter_tests.php b/tests/xss_filter_tests.php deleted file mode 100644 index 2d29e390a2..0000000000 --- a/tests/xss_filter_tests.php +++ /dev/null @@ -1,140 +0,0 @@ -' - -$validstring=notags($invalidstring); -$escapedString=escape_tags($invalidstring); - -assert("[submit type="button" onclick="alert(\'failed!\');" /]", $validstring); -assert("what ever", $escapedString); - -/** -*autonames should be random, even length -*/ -$autoname1=autoname(10); -$autoname2=autoname(10); - -assertNotEquals($autoname1, $autoname2); - -/** -*autonames should be random, odd length -*/ -$autoname1=autoname(9); -$autoname2=autoname(9); - -assertNotEquals($autoname1, $autoname2); - -/** -* try to fail autonames -*/ -$autoname1=autoname(0); -$autoname2=autoname(MAX_VALUE); -$autoname3=autoname(1); -assert(count($autoname1), 0); -assert(count($autoname2), MAX_VALUE); -assert(count($autoname3), 1); - -/** -*xmlify and unxmlify -*/ -$text="I want to break\n this!11!" -$xml=xmlify($text); //test whether it actually may be part of a xml document -$retext=unxmlify($text); - -assert($text, $retext); - -/** -* test hex2bin and reverse -*/ - -assert(-3, hex2bin(bin2hex(-3))); -assert(0, hex2bin(bin2hex(0))); -assert(12, hex2bin(bin2hex(12))); -assert(MAX_INT, hex2bin(bin2hex(MAX_INT))); - -/** -* test expand_acl -*/ -$text="<1><2><3>"; -assert(array(1, 2, 3), $text); - -$text="<1><279012><15>"; -assert(array(1, 279012, 15), $text); - -$text="<1><279012>"; //maybe that's invalid -assert(array(1, 279012, "tt"), $text); - -$text="<1><279 012>"; //maybe that's invalid -assert(array(1, "279 012", "tt"), $text); - -$text=""; //maybe that's invalid -assert(array(), $text); - -$text="According to documentation, that's invalid. "; //should be invalid -assert(array(), $text); - -$text=" From fbd7e8f8ba4a2736b231ee254e205b36e28d17cc Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Thu, 8 Mar 2012 17:44:57 +0100 Subject: [PATCH 03/11] excludes reports from git --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6302bc1c8b..2531fe4cdd 100755 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ addon #ignore documentation, it should be newly built doc/api +#ignore reports, should be generted with every build +report/ + #ignore config files from eclipse, we don't want IDE files in our repository .project .buildpath From 2e3116a11e020cd1f2bbe00b03c77210aad33fe5 Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Thu, 8 Mar 2012 17:46:40 +0100 Subject: [PATCH 04/11] added library and include to .htaccess --- .htaccess | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.htaccess b/.htaccess index 1df5096702..5f9531a7eb 100755 --- a/.htaccess +++ b/.htaccess @@ -5,6 +5,9 @@ AddType audio/ogg .oga Deny from all + +Deny from all + RewriteEngine on From f84c191f8df126b95d8a41f70e785a9592018390 Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Fri, 9 Mar 2012 12:16:58 +0100 Subject: [PATCH 05/11] added some tests --- build.xml | 28 ++++----- tests/xss_filter_test.php | 116 +++++++++++++++++++++++++++++--------- util/db_update.php | 2 +- 3 files changed, 102 insertions(+), 44 deletions(-) diff --git a/build.xml b/build.xml index 0f57450726..a61a5123d7 100644 --- a/build.xml +++ b/build.xml @@ -1,16 +1,6 @@ - - - set_include_path( - get_include_path() . PATH_SEPARATOR - . 'include' . PATH_SEPARATOR - . 'library' . PATH_SEPARATOR - . 'library/phpsec' . PATH_SEPARATOR - . '.' ); - - @@ -32,16 +22,17 @@ - + + @@ -50,9 +41,9 @@ - + @@ -75,6 +66,9 @@ + + + diff --git a/tests/xss_filter_test.php b/tests/xss_filter_test.php index e480ef7ec0..00e97cf98e 100644 --- a/tests/xss_filter_test.php +++ b/tests/xss_filter_test.php @@ -1,16 +1,26 @@ '; @@ -53,12 +63,12 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $autoname1=autoname(-23); $this->assertEquals(0, count($autoname1)); } - -// public function testAutonameMaxLength() { -// $autoname2=autoname(PHP_INT_MAX); -// $this->assertEquals(PHP_INT_MAX, count($autoname2)); -// } - + + // public function testAutonameMaxLength() { + // $autoname2=autoname(PHP_INT_MAX); + // $this->assertEquals(PHP_INT_MAX, count($autoname2)); + // } + public function testAutonameLength1() { $autoname3=autoname(1); $this->assertEquals(1, count($autoname3)); @@ -68,7 +78,7 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { *xmlify and unxmlify */ public function testXmlify() { - $text="I want to break\n this!11!"; + $text="I want to break\n this!11!"; $xml=xmlify($text); //test whether it actually may be part of a xml document $retext=unxmlify($text); @@ -85,7 +95,7 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $this->assertEquals(12, hex2bin(bin2hex(12))); $this->assertEquals(PHP_INT_MAX, hex2bin(bin2hex(PHP_INT_MAX))); } - + /** * test expand_acl */ @@ -93,7 +103,7 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $text="<1><2><3>"; $this->assertEquals(array(1, 2, 3), expand_acl($text)); } - + public function testExpandAclBigNumber() { $text="<1><279012><15>"; $this->assertEquals(array(1, 279012, 15), expand_acl($text)); @@ -133,19 +143,19 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $text="Another> invalid> string>"; //should be invalid $this->assertEquals(array(), expand_acl($text)); } - + public function testExpandAclOpenOnly() { $text="assertEquals(array(), expand_acl($text)); } - + public function testExpandAclNoMatching1() { $text=" invalid "; //should be invalid $this->assertEquals(array(), expand_acl($text)); } - + public function testExpandAclNoMatching2() { - $text="<1>2><3>"; + $text="<1>2><3>"; $this->assertEquals(array(), expand_acl($text)); } @@ -166,7 +176,7 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $this->assertTrue(attribute_contains($testAttr, "class3")); $this->assertFalse(attribute_contains($testAttr, "class2")); } - + public function testAttributeContainsEmpty() { $testAttr=""; $this->assertFalse(attribute_contains($testAttr, "class2")); @@ -176,17 +186,71 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $testAttr="--... %\$ä() /(=?}"; $this->assertFalse(attribute_contains($testAttr, "class2")); } - + /** * test get_tags */ + public function testGetTagsShortPerson() { + $text="hi @Mike"; + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + } + + public function testGetTagsShortTag() { + $text="This is a #test_case"; + + $tags=get_tags($text); + + $this->assertEquals("#test_case", $tags[0]); + } + + public function testGetTagsShortTagAndPerson() { + $text="hi @Mike This is a #test_case"; + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("#test_case", $tags[1]); + } + + public function testGetTagsShortTagAndPersonSpecialChars() { + $text="hi @Mike, This is a #test_case."; + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("#test_case", $tags[1]); + } + + public function testGetTagsPersonOnly() { + $text="@Mike I saw the Theme Dev group was created."; + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + } + + public function testGetTags2Persons1TagSpecialChars() { + $text="hi @Mike, I'm just writing #test_cases, so" + ." so @somebody@friendica.com may change #things."; + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("#test_cases", $tags[1]); + $this->assertEquals("@somebody@friendica.com", $tags[2]); + $this->assertEquals("#things", $tags[3]); + } + public function testGetTags() { $text="hi @Mike, I'm just writing #test_cases, " ." so @somebody@friendica.com may change #things. Of course I " ."look for a lot of #pitfalls, like #tags at the end of a sentence " ."@comment. I hope noone forgets about @fullstops.because that might" ." break #things. @Mike@campino@friendica.eu is also #nice, isn't it? " - ."Now, add a @first_last tag. "; + ."Now, add a @first_last tag. "; //check whether this are all variants (no, auto-stuff is missing). $tags=get_tags($text); @@ -210,8 +274,8 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $tags=get_tags(""); $this->assertEquals(0, count($tags)); } -//function qp, quick and dirty?? -//get_mentions -//get_contact_block, bis Zeile 538 + //function qp, quick and dirty?? + //get_mentions + //get_contact_block, bis Zeile 538 } ?> diff --git a/util/db_update.php b/util/db_update.php index a6177324ac..35620e80b7 100755 --- a/util/db_update.php +++ b/util/db_update.php @@ -26,7 +26,7 @@ echo "New DB VERSION: " . DB_UPDATE_VERSION . "\n"; if($build != DB_UPDATE_VERSION) { echo "Updating database..."; - check_config(); + check_config($a); echo "Done\n"; } From 21589c5eced7869d7105fa439c433e6a12c89531 Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Fri, 9 Mar 2012 12:18:37 +0100 Subject: [PATCH 06/11] changed a test string --- tests/xss_filter_test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/xss_filter_test.php b/tests/xss_filter_test.php index 00e97cf98e..35d3b1be9e 100644 --- a/tests/xss_filter_test.php +++ b/tests/xss_filter_test.php @@ -225,11 +225,11 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { } public function testGetTagsPersonOnly() { - $text="@Mike I saw the Theme Dev group was created."; + $text="@Test I saw the Theme Dev group was created."; $tags=get_tags($text); - $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("@Test", $tags[0]); } public function testGetTags2Persons1TagSpecialChars() { From f8042d04451905486fb766c520736f4060ae9a12 Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Fri, 9 Mar 2012 12:57:11 +0100 Subject: [PATCH 07/11] splitted test cases. --- mod/item.php | 212 +++++++++++++++++++------------------- tests/get_tags_test.php | 147 ++++++++++++++++++++++++++ tests/xss_filter_test.php | 88 ---------------- 3 files changed, 255 insertions(+), 192 deletions(-) create mode 100644 tests/get_tags_test.php diff --git a/mod/item.php b/mod/item.php index 81d7c753b4..a9edf0da66 100755 --- a/mod/item.php +++ b/mod/item.php @@ -425,110 +425,7 @@ function item_post(&$a) { if(count($tags)) { foreach($tags as $tag) { - - if(isset($profile)) - unset($profile); - if(strpos($tag,'#') === 0) { - if(strpos($tag,'[url=')) - continue; - $basetag = str_replace('_',' ',substr($tag,1)); - $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body); - - $newtag = '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]'; - if(! stristr($str_tags,$newtag)) { - if(strlen($str_tags)) - $str_tags .= ','; - $str_tags .= $newtag; - } - continue; - } - if(strpos($tag,'@') === 0) { - if(strpos($tag,'[url=')) - continue; - $stat = false; - $name = substr($tag,1); - if((strpos($name,'@')) || (strpos($name,'http://'))) { - $newname = $name; - $links = @lrdd($name); - if(count($links)) { - foreach($links as $link) { - if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') - $profile = $link['@attributes']['href']; - if($link['@attributes']['rel'] === 'salmon') { - if(strlen($inform)) - $inform .= ','; - $inform .= 'url:' . str_replace(',','%2c',$link['@attributes']['href']); - } - } - } - } - else { - $newname = $name; - $alias = ''; - $tagcid = 0; - if(strrpos($newname,'+')) { - $tagcid = intval(substr($newname,strrpos($newname,'+') + 1)); - if(strpos($name,' ')) - $name = substr($name,0,strpos($name,' ')); - } - if($tagcid) { - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($tagcid), - intval($profile_uid) - ); - } - elseif(strstr($name,'_') || strstr($name,' ')) { - $newname = str_replace('_',' ',$name); - $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", - dbesc($newname), - intval($profile_uid) - ); - } - else { - $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", - dbesc($name), - dbesc($name), - intval($profile_uid) - ); - } - if(count($r)) { - $profile = $r[0]['url']; - if($r[0]['network'] === 'stat') { - $newname = $r[0]['nick']; - $stat = true; - if($r[0]['alias']) - $alias = $r[0]['alias']; - } - else - $newname = $r[0]['name']; - if(strlen($inform)) - $inform .= ','; - $inform .= 'cid:' . $r[0]['id']; - } - } - if($profile) { - $body = str_replace('@' . $name, '@' . '[url=' . $profile . ']' . $newname . '[/url]', $body); - $profile = str_replace(',','%2c',$profile); - $newtag = '@[url=' . $profile . ']' . $newname . '[/url]'; - if(! stristr($str_tags,$newtag)) { - if(strlen($str_tags)) - $str_tags .= ','; - $str_tags .= $newtag; - } - - // Status.Net seems to require the numeric ID URL in a mention if the person isn't - // subscribed to you. But the nickname URL is OK if they are. Grrr. We'll tag both. - - if(strlen($alias)) { - $newtag = '@[url=' . $alias . ']' . $newname . '[/url]'; - if(! stristr($str_tags,$newtag)) { - if(strlen($str_tags)) - $str_tags .= ','; - $str_tags .= $newtag; - } - } - } - } + handle_tag($body, $inform, $str_tags, $profile_uid, $tag); } } @@ -922,3 +819,110 @@ function item_content(&$a) { drop_item($a->argv[2]); } } + +function handle_body(&$body, &$inform, &$str_tags, $profile_uid, $tag) { + $profile=null; + if(isset($profile)) + unset($profile); + if(strpos($tag,'#') === 0) { + if(strpos($tag,'[url=')) + continue; + $basetag = str_replace('_',' ',substr($tag,1)); + $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body); + + $newtag = '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]'; + if(! stristr($str_tags,$newtag)) { + if(strlen($str_tags)) + $str_tags .= ','; + $str_tags .= $newtag; + } + continue; + } + if(strpos($tag,'@') === 0) { + if(strpos($tag,'[url=')) + continue; + $stat = false; + $name = substr($tag,1); + if((strpos($name,'@')) || (strpos($name,'http://'))) { + $newname = $name; + $links = @lrdd($name); + if(count($links)) { + foreach($links as $link) { + if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') + $profile = $link['@attributes']['href']; + if($link['@attributes']['rel'] === 'salmon') { + if(strlen($inform)) + $inform .= ','; + $inform .= 'url:' . str_replace(',','%2c',$link['@attributes']['href']); + } + } + } + } + else { + $newname = $name; + $alias = ''; + $tagcid = 0; + if(strrpos($newname,'+')) { + $tagcid = intval(substr($newname,strrpos($newname,'+') + 1)); + if(strpos($name,' ')) + $name = substr($name,0,strpos($name,' ')); + } + if($tagcid) { + $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($tagcid), + intval($profile_uid) + ); + } + elseif(strstr($name,'_') || strstr($name,' ')) { + $newname = str_replace('_',' ',$name); + $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", + dbesc($newname), + intval($profile_uid) + ); + } + else { + $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", + dbesc($name), + dbesc($name), + intval($profile_uid) + ); + } + if(count($r)) { + $profile = $r[0]['url']; + if($r[0]['network'] === 'stat') { + $newname = $r[0]['nick']; + $stat = true; + if($r[0]['alias']) + $alias = $r[0]['alias']; + } + else + $newname = $r[0]['name']; + if(strlen($inform)) + $inform .= ','; + $inform .= 'cid:' . $r[0]['id']; + } + } + if($profile) { + $body = str_replace('@' . $name, '@' . '[url=' . $profile . ']' . $newname . '[/url]', $body); + $profile = str_replace(',','%2c',$profile); + $newtag = '@[url=' . $profile . ']' . $newname . '[/url]'; + if(! stristr($str_tags,$newtag)) { + if(strlen($str_tags)) + $str_tags .= ','; + $str_tags .= $newtag; + } + + // Status.Net seems to require the numeric ID URL in a mention if the person isn't + // subscribed to you. But the nickname URL is OK if they are. Grrr. We'll tag both. + + if(strlen($alias)) { + $newtag = '@[url=' . $alias . ']' . $newname . '[/url]'; + if(! stristr($str_tags,$newtag)) { + if(strlen($str_tags)) + $str_tags .= ','; + $str_tags .= $newtag; + } + } + } + } +} diff --git a/tests/get_tags_test.php b/tests/get_tags_test.php new file mode 100644 index 0000000000..a458f0fbc5 --- /dev/null +++ b/tests/get_tags_test.php @@ -0,0 +1,147 @@ +15, 'network'=>'stat', 'alias'=>'Mike', 'nick'=>'Mike', 'url'=>"http://justatest.de")); + +} +function dbesc($str) { + echo $str; +} + +class GetTagsTest extends PHPUnit_Framework_TestCase { + + public function setUp() { + set_include_path( + get_include_path() . PATH_SEPARATOR + . 'include' . PATH_SEPARATOR + . 'library' . PATH_SEPARATOR + . 'library/phpsec' . PATH_SEPARATOR + . '.' ); + } + + /** + * test with one Person tag + */ + public function testGetTagsShortPerson() { + $text="hi @Mike"; + + $tags=get_tags($text); + + $inform=''; + $str_tags=''; + handle_body($text, $inform, $str_tags, 11, $tags[0]); + + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals($text, "hi @[url=http://justatest.de]Mike[/url]"); + } + + /** + * Test with one hash tag. + */ + public function testGetTagsShortTag() { + $text="This is a #test_case"; + + $tags=get_tags($text); + + $this->assertEquals("#test_case", $tags[0]); + } + + /** + * test with a person and a hash tag + */ + public function testGetTagsShortTagAndPerson() { + $text="hi @Mike This is a #test_case"; + + $tags=get_tags($text); + + $inform=''; + $str_tags=''; + handle_body($text, $inform, $str_tags, 11, $tags[0]); + + $this->assertEquals("hi @[url=http://justatest.de]Mike[/url] This is a #test_case", $text); + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("#test_case", $tags[1]); + } + + /** + * test with a person, a hash tag and some special chars. + */ + public function testGetTagsShortTagAndPersonSpecialChars() { + $text="hi @Mike, This is a #test_case."; + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("#test_case", $tags[1]); + } + + /** + * Test with a person tag and text behind it. + */ + public function testGetTagsPersonOnly() { + $text="@Test I saw the Theme Dev group was created."; + + $tags=get_tags($text); + + $this->assertEquals("@Test", $tags[0]); + } + + /** + * test with two persons and one special tag. + */ + public function testGetTags2Persons1TagSpecialChars() { + $text="hi @Mike, I'm just writing #test_cases, so" + ." so @somebody@friendica.com may change #things."; + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("#test_cases", $tags[1]); + $this->assertEquals("@somebody@friendica.com", $tags[2]); + $this->assertEquals("#things", $tags[3]); + } + + /** + * test with a long text. + */ + public function testGetTags() { + $text="hi @Mike, I'm just writing #test_cases, " + ." so @somebody@friendica.com may change #things. Of course I " + ."look for a lot of #pitfalls, like #tags at the end of a sentence " + ."@comment. I hope noone forgets about @fullstops.because that might" + ." break #things. @Mike@campino@friendica.eu is also #nice, isn't it? " + ."Now, add a @first_last tag. "; + //TODO check whether this are all variants (no, auto-stuff is missing). + + $tags=get_tags($text); + + $this->assertEquals("@Mike", $tags[0]); + $this->assertEquals("#test_cases", $tags[1]); + $this->assertEquals("@somebody@friendica.com", $tags[2]); + $this->assertEquals("#things", $tags[3]); + $this->assertEquals("#pitfalls", $tags[4]); + $this->assertEquals("#tags", $tags[5]); + $this->assertEquals("@comment", $tags[6]); + $this->assertEquals("@fullstops", $tags[7]); + $this->assertEquals("#things", $tags[8]); + $this->assertEquals("@Mike", $tags[9]); + $this->assertEquals("@campino@friendica.eu", $tags[10]); + $this->assertEquals("#nice", $tags[11]); + $this->assertEquals("@first_last", $tags[12]); + } + + /** + * test with an empty string + */ + public function testGetTagsEmpty() { + $tags=get_tags(""); + $this->assertEquals(0, count($tags)); + } +} \ No newline at end of file diff --git a/tests/xss_filter_test.php b/tests/xss_filter_test.php index 35d3b1be9e..fe944c2a74 100644 --- a/tests/xss_filter_test.php +++ b/tests/xss_filter_test.php @@ -1,6 +1,5 @@ assertFalse(attribute_contains($testAttr, "class2")); } - /** - * test get_tags - */ - public function testGetTagsShortPerson() { - $text="hi @Mike"; - - $tags=get_tags($text); - - $this->assertEquals("@Mike", $tags[0]); - } - - public function testGetTagsShortTag() { - $text="This is a #test_case"; - - $tags=get_tags($text); - - $this->assertEquals("#test_case", $tags[0]); - } - - public function testGetTagsShortTagAndPerson() { - $text="hi @Mike This is a #test_case"; - - $tags=get_tags($text); - - $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals("#test_case", $tags[1]); - } - - public function testGetTagsShortTagAndPersonSpecialChars() { - $text="hi @Mike, This is a #test_case."; - - $tags=get_tags($text); - - $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals("#test_case", $tags[1]); - } - - public function testGetTagsPersonOnly() { - $text="@Test I saw the Theme Dev group was created."; - - $tags=get_tags($text); - - $this->assertEquals("@Test", $tags[0]); - } - - public function testGetTags2Persons1TagSpecialChars() { - $text="hi @Mike, I'm just writing #test_cases, so" - ." so @somebody@friendica.com may change #things."; - - $tags=get_tags($text); - - $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals("#test_cases", $tags[1]); - $this->assertEquals("@somebody@friendica.com", $tags[2]); - $this->assertEquals("#things", $tags[3]); - } - - public function testGetTags() { - $text="hi @Mike, I'm just writing #test_cases, " - ." so @somebody@friendica.com may change #things. Of course I " - ."look for a lot of #pitfalls, like #tags at the end of a sentence " - ."@comment. I hope noone forgets about @fullstops.because that might" - ." break #things. @Mike@campino@friendica.eu is also #nice, isn't it? " - ."Now, add a @first_last tag. "; - //check whether this are all variants (no, auto-stuff is missing). - - $tags=get_tags($text); - - $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals("#test_cases", $tags[1]); - $this->assertEquals("@somebody@friendica.com", $tags[2]); - $this->assertEquals("#things", $tags[3]); - $this->assertEquals("#pitfalls", $tags[4]); - $this->assertEquals("#tags", $tags[5]); - $this->assertEquals("@comment", $tags[6]); - $this->assertEquals("@fullstops", $tags[7]); - $this->assertEquals("#things", $tags[8]); - $this->assertEquals("@Mike", $tags[9]); - $this->assertEquals("@campino@friendica.eu", $tags[10]); - $this->assertEquals("#nice", $tags[11]); - $this->assertEquals("@first_last", $tags[12]); - } - - public function testGetTagsEmpty() { - $tags=get_tags(""); - $this->assertEquals(0, count($tags)); - } //function qp, quick and dirty?? //get_mentions //get_contact_block, bis Zeile 538 From bce3bfff38ad6f540dca39f6ed5b1d8cae19edb1 Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Mon, 12 Mar 2012 13:59:00 +0100 Subject: [PATCH 08/11] get tags test improved --- mod/item.php | 79 ++++++++++++++++++++++++++++------------- tests/get_tags_test.php | 40 +++++++++++++++++++-- 2 files changed, 92 insertions(+), 27 deletions(-) diff --git a/mod/item.php b/mod/item.php index a9edf0da66..0ff7f6a7c8 100755 --- a/mod/item.php +++ b/mod/item.php @@ -820,33 +820,54 @@ function item_content(&$a) { } } +/** + * This function removes the tag $tag from the text $body and replaces it with + * the appropiate link. + * + * @param unknown_type $body the text to replace the tag in + * @param unknown_type $inform a comma-seperated string containing everybody to inform + * @param unknown_type $str_tags string to add the tag to + * @param unknown_type $profile_uid + * @param unknown_type $tag the tag to replace + */ function handle_body(&$body, &$inform, &$str_tags, $profile_uid, $tag) { - $profile=null; - if(isset($profile)) - unset($profile); + //is it a hash tag? if(strpos($tag,'#') === 0) { - if(strpos($tag,'[url=')) - continue; + //if the tag is replaced... + if(strpos($tag,'[url=')) + //...do nothing + continue; + //base tag has the tags name only $basetag = str_replace('_',' ',substr($tag,1)); - $body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body); - - $newtag = '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]'; + //create text for link + $newtag = '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]'; + //replace tag by the link + $body = str_replace($tag, $newtag, $body); + + //is the link already in str_tags? if(! stristr($str_tags,$newtag)) { + //append or set str_tags if(strlen($str_tags)) $str_tags .= ','; $str_tags .= $newtag; } continue; - } + } + //is it a person tag? if(strpos($tag,'@') === 0) { + //is it already replaced? if(strpos($tag,'[url=')) continue; $stat = false; - $name = substr($tag,1); + //get the person's name + $name = substr($tag,1); + //is it a link or a full dfrn address? if((strpos($name,'@')) || (strpos($name,'http://'))) { $newname = $name; + //get the profile links $links = @lrdd($name); if(count($links)) { + //for all links, collect how is to inform and how's profile is to link foreach($links as $link) { if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') $profile = $link['@attributes']['href']; @@ -857,38 +878,44 @@ function handle_body(&$body, &$inform, &$str_tags, $profile_uid, $tag) { } } } - } - else { + } else { //if it is a name rather than an address $newname = $name; $alias = ''; - $tagcid = 0; + $tagcid = 0; + //is it some generated name? if(strrpos($newname,'+')) { + //get the id $tagcid = intval(substr($newname,strrpos($newname,'+') + 1)); + //remove the next word from tag's name if(strpos($name,' ')) $name = substr($name,0,strpos($name,' ')); - } - if($tagcid) { + } + if($tagcid) { //if there was an id + //select contact with that id from the logged in user's contact list $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($tagcid), intval($profile_uid) ); - } - elseif(strstr($name,'_') || strstr($name,' ')) { + } elseif(strstr($name,'_') || strstr($name,' ')) { //no id + //get the real name $newname = str_replace('_',' ',$name); + //select someone from this user's contacts by name $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", dbesc($newname), intval($profile_uid) ); - } - else { + } else { + //select someone by attag or nick and the name passed in $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", dbesc($name), dbesc($name), intval($profile_uid) ); - } + } + //$r is set, if someone could be selected if(count($r)) { - $profile = $r[0]['url']; + $profile = $r[0]['url']; + //set newname to nick, find alias if($r[0]['network'] === 'stat') { $newname = $r[0]['nick']; $stat = true; @@ -897,15 +924,19 @@ function handle_body(&$body, &$inform, &$str_tags, $profile_uid, $tag) { } else $newname = $r[0]['name']; + //add person's id to $inform if(strlen($inform)) $inform .= ','; $inform .= 'cid:' . $r[0]['id']; } - } - if($profile) { - $body = str_replace('@' . $name, '@' . '[url=' . $profile . ']' . $newname . '[/url]', $body); + } + //if there is an url for this persons profile + if(isset($profile)) { + //create profile link $profile = str_replace(',','%2c',$profile); $newtag = '@[url=' . $profile . ']' . $newname . '[/url]'; + $body = str_replace('@' . $name, $newtag, $body); + //append tag to str_tags if(! stristr($str_tags,$newtag)) { if(strlen($str_tags)) $str_tags .= ','; diff --git a/tests/get_tags_test.php b/tests/get_tags_test.php index a458f0fbc5..ee2daced10 100644 --- a/tests/get_tags_test.php +++ b/tests/get_tags_test.php @@ -8,11 +8,45 @@ require_once 'include/text.php'; require_once 'mod/item.php'; function q($sql) { - return array(array('id'=>15, 'network'=>'stat', 'alias'=>'Mike', 'nick'=>'Mike', 'url'=>"http://justatest.de")); + + $result=array(array('id'=>15, + 'attag'=>'', 'network'=>'dfrn', + 'name'=>'Mike Lastname', 'alias'=>'Mike', + 'nick'=>'Mike', 'url'=>"http://justatest.de")); + + $args=func_get_args(); + $str=""; + foreach($args as $arg) { + $str.=", ".$arg; + } + + //last parameter is always (in this test) uid, so, it should be 11 + if($args[count($args)-1]!=11) { + throw new Exception("q from get_tags_test was used and uid was not 11. "); + } + + if(2==count($args)) { + //first call in handle_body, id only + if($result[0]['id']===$args[1]) { + return $result; + } + throw new Exception($str); + //second call in handle_body, name + if($result[0]['name']===$args[1]) { + return $result; + } + } + throw new Exception($str); + //third call in handle_body, nick or attag + if($result[0]['nick']===$args[2] || $result[0]['attag']===$args[1]) { + return $result; + } +// throw new Exception("Nothing fitted: ".$args[1].", ".$args[2]); } + function dbesc($str) { - echo $str; + return $str; } class GetTagsTest extends PHPUnit_Framework_TestCase { @@ -39,7 +73,7 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { handle_body($text, $inform, $str_tags, 11, $tags[0]); $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals($text, "hi @[url=http://justatest.de]Mike[/url]"); + $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url]", $text); } /** From 509532d168bf716eb24e030ab59476a88ab91571 Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Wed, 14 Mar 2012 12:30:52 +0100 Subject: [PATCH 09/11] get_tags tests corrected. They test for the right things now. --- mod/item.php | 13 ++- tests/get_tags_test.php | 243 +++++++++++++++++++++++++++++++--------- 2 files changed, 195 insertions(+), 61 deletions(-) diff --git a/mod/item.php b/mod/item.php index 0ff7f6a7c8..e4336b974c 100755 --- a/mod/item.php +++ b/mod/item.php @@ -425,7 +425,7 @@ function item_post(&$a) { if(count($tags)) { foreach($tags as $tag) { - handle_tag($body, $inform, $str_tags, $profile_uid, $tag); + handle_tag($a, $body, $inform, $str_tags, $profile_uid, $tag); } } @@ -830,7 +830,7 @@ function item_content(&$a) { * @param unknown_type $profile_uid * @param unknown_type $tag the tag to replace */ -function handle_body(&$body, &$inform, &$str_tags, $profile_uid, $tag) { +function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { //is it a hash tag? if(strpos($tag,'#') === 0) { //if the tag is replaced... @@ -851,7 +851,7 @@ function handle_body(&$body, &$inform, &$str_tags, $profile_uid, $tag) { $str_tags .= ','; $str_tags .= $newtag; } - continue; + return; } //is it a person tag? if(strpos($tag,'@') === 0) { @@ -887,14 +887,15 @@ function handle_body(&$body, &$inform, &$str_tags, $profile_uid, $tag) { //get the id $tagcid = intval(substr($newname,strrpos($newname,'+') + 1)); //remove the next word from tag's name - if(strpos($name,' ')) - $name = substr($name,0,strpos($name,' ')); + if(strpos($name,' ')) { + $name = substr($name,0,strpos($name,' ')); + } } if($tagcid) { //if there was an id //select contact with that id from the logged in user's contact list $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($tagcid), - intval($profile_uid) + intval($profile_uid) ); } elseif(strstr($name,'_') || strstr($name,' ')) { //no id //get the real name diff --git a/tests/get_tags_test.php b/tests/get_tags_test.php index ee2daced10..bde2db7d09 100644 --- a/tests/get_tags_test.php +++ b/tests/get_tags_test.php @@ -1,14 +1,41 @@ 15, 'attag'=>'', 'network'=>'dfrn', 'name'=>'Mike Lastname', 'alias'=>'Mike', @@ -16,48 +43,59 @@ function q($sql) { $args=func_get_args(); - $str=""; - foreach($args as $arg) { - $str.=", ".$arg; - } - //last parameter is always (in this test) uid, so, it should be 11 if($args[count($args)-1]!=11) { - throw new Exception("q from get_tags_test was used and uid was not 11. "); + return; } - if(2==count($args)) { + + if(3==count($args)) { //first call in handle_body, id only - if($result[0]['id']===$args[1]) { + if($result[0]['id']==$args[1]) { return $result; } - throw new Exception($str); //second call in handle_body, name if($result[0]['name']===$args[1]) { return $result; } } - throw new Exception($str); //third call in handle_body, nick or attag if($result[0]['nick']===$args[2] || $result[0]['attag']===$args[1]) { return $result; } -// throw new Exception("Nothing fitted: ".$args[1].", ".$args[2]); } +/** + * replacement for dbesc. + * I don't want to test dbesc here, so + * I just return the input. It won't be a problem, because + * the test does not use a real database. + * + * DON'T USE HAT FUNCTION OUTSIDE A TEST! + * + * @param string $str + * @return input + */ function dbesc($str) { return $str; } -class GetTagsTest extends PHPUnit_Framework_TestCase { - +/** + * TestCase for tag handling. + * + * @author alexander + * @package test.util + */ +class GetTagsTest extends PHPUnit_Framework_TestCase { + /** the mock to use as app */ + private $a; + + /** + * initialize the test. That's a phpUnit function, + * don't change its name. + */ public function setUp() { - set_include_path( - get_include_path() . PATH_SEPARATOR - . 'include' . PATH_SEPARATOR - . 'library' . PATH_SEPARATOR - . 'library/phpsec' . PATH_SEPARATOR - . '.' ); + $this->a=new MockApp(); } /** @@ -70,10 +108,54 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { $inform=''; $str_tags=''; - handle_body($text, $inform, $str_tags, 11, $tags[0]); - - $this->assertEquals("@Mike", $tags[0]); + foreach($tags as $tag) { + handle_tag($this->a, $text, $inform, $str_tags, 11, $tag); + } + + //correct tags found? + $this->assertEquals(1, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); + + //correct output from handle_tag? + $this->assertEquals("cid:15", $inform); + $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url]", $text); + } + + /** + * test with one Person tag. + * There's a minor spelling mistake... + */ + public function testGetTagsShortPersonSpelling() { + $text="hi @Mike.because"; + + $tags=get_tags($text); + + //correct tags found? + $this->assertEquals(1, count($tags)); + $this->assertTrue(in_array("@Mike.because", $tags)); + + $inform=''; + $str_tags=''; + handle_tag($this->a, $text, $inform, $str_tags, 11, $tags[0]); + + $this->assertEquals("cid:15", $inform); + $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); + $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url].because", $text); + } + + /** + * test with two Person tags. + * There's a minor spelling mistake... + */ + public function testGetTagsPerson2Spelling() { + $text="hi @Mike@campino@friendica.eu"; + + $tags=get_tags($text); + + $this->assertEquals(2, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("@campino@friendica.eu", $tags)); } /** @@ -83,8 +165,9 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { $text="This is a #test_case"; $tags=get_tags($text); - - $this->assertEquals("#test_case", $tags[0]); + + $this->assertEquals(1, count($tags)); + $this->assertTrue(in_array("#test_case", $tags)); } /** @@ -95,13 +178,21 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { $tags=get_tags($text); - $inform=''; - $str_tags=''; - handle_body($text, $inform, $str_tags, 11, $tags[0]); - - $this->assertEquals("hi @[url=http://justatest.de]Mike[/url] This is a #test_case", $text); - $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals("#test_case", $tags[1]); + $this->assertEquals(3, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("@Mike This", $tags)); + $this->assertTrue(in_array("#test_case", $tags)); + + $inform=''; + $str_tags=''; + foreach($tags as $tag) { + handle_tag($this->a, $text, $inform, $str_tags, 11, $tag); + } + + $this->assertEquals("cid:15", $inform); + $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url],#[url=baseurl/search?search=test%20case]test case[/url]", $str_tags); + $this->assertEquals("hi @[url=http://justatest.de]Mike Lastname[/url] This is a #[url=baseurl/search?search=test%20case]test case[/url]", $text); + } /** @@ -112,8 +203,9 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { $tags=get_tags($text); - $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals("#test_case", $tags[1]); + $this->assertEquals(2, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("#test_case", $tags)); } /** @@ -123,10 +215,45 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { $text="@Test I saw the Theme Dev group was created."; $tags=get_tags($text); - - $this->assertEquals("@Test", $tags[0]); + + $this->assertEquals(2, count($tags)); + $this->assertTrue(in_array("@Test I", $tags)); + $this->assertTrue(in_array("@Test", $tags)); } + /** + * this test demonstrates strange behaviour by intval. + * It makes the next test fail. + */ + public function testIntval() { + $this->assertEquals(15, intval("15 it")); + } + + /** + * test a tag with an id in it + */ + public function testIdTag() { + $text="Test with @mike+15 id tag"; + + $tags=get_tags($text); + + $this->assertEquals(2, count($tags)); + $this->assertTrue(in_array("@mike+15", $tags)); + + //happens right now, but it shouldn't be necessary + $this->assertTrue(in_array("@mike+15 id", $tags)); + + $inform=''; + $str_tags=''; + foreach($tags as $tag) { + handle_tag($this->a, $text, $inform, $str_tags, 11, $tag); + } + + $this->assertEquals("Test with @[url=http://justatest.de]Mike Lastname[/url] id tag", $text); + $this->assertEquals("@[url=http://justatest.de]Mike Lastname[/url]", $str_tags); + $this->assertEquals("cid:15", $inform); + } + /** * test with two persons and one special tag. */ @@ -135,11 +262,13 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { ." so @somebody@friendica.com may change #things."; $tags=get_tags($text); - - $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals("#test_cases", $tags[1]); - $this->assertEquals("@somebody@friendica.com", $tags[2]); - $this->assertEquals("#things", $tags[3]); + + $this->assertEquals(5, count($tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("#test_cases", $tags)); + $this->assertTrue(in_array("@somebody@friendica.com", $tags)); + $this->assertTrue(in_array("@somebody@friendica.com may", $tags)); + $this->assertTrue(in_array("#things", $tags)); } /** @@ -156,19 +285,23 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { $tags=get_tags($text); - $this->assertEquals("@Mike", $tags[0]); - $this->assertEquals("#test_cases", $tags[1]); - $this->assertEquals("@somebody@friendica.com", $tags[2]); - $this->assertEquals("#things", $tags[3]); - $this->assertEquals("#pitfalls", $tags[4]); - $this->assertEquals("#tags", $tags[5]); - $this->assertEquals("@comment", $tags[6]); - $this->assertEquals("@fullstops", $tags[7]); - $this->assertEquals("#things", $tags[8]); - $this->assertEquals("@Mike", $tags[9]); - $this->assertEquals("@campino@friendica.eu", $tags[10]); - $this->assertEquals("#nice", $tags[11]); - $this->assertEquals("@first_last", $tags[12]); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("#test_cases", $tags)); + $this->assertTrue(in_array("@somebody@friendica.com", $tags)); + $this->assertTrue(in_array("#things", $tags)); + $this->assertTrue(in_array("#pitfalls", $tags)); + $this->assertTrue(in_array("#tags", $tags)); + $this->assertTrue(in_array("@comment", $tags)); + $this->assertTrue(in_array("@fullstops.because", $tags)); + $this->assertTrue(in_array("#things", $tags)); + $this->assertTrue(in_array("@Mike", $tags)); + $this->assertTrue(in_array("#nice", $tags)); + $this->assertTrue(in_array("@first_last", $tags)); + + //right now, none of the is matched + $this->assertFalse(in_array("@Mike@campino@friendica.eu", $tags)); + $this->assertTrue(in_array("@campino@friendica.eu", $tags)); + $this->assertTrue(in_array("@campino@friendica.eu is", $tags)); } /** From c0c98206ef322b3d175d5348d37e8d0b5fca140b Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Wed, 14 Mar 2012 12:31:25 +0100 Subject: [PATCH 10/11] removed done TODO --- tests/get_tags_test.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/get_tags_test.php b/tests/get_tags_test.php index bde2db7d09..9051923be0 100644 --- a/tests/get_tags_test.php +++ b/tests/get_tags_test.php @@ -281,8 +281,7 @@ class GetTagsTest extends PHPUnit_Framework_TestCase { ."@comment. I hope noone forgets about @fullstops.because that might" ." break #things. @Mike@campino@friendica.eu is also #nice, isn't it? " ."Now, add a @first_last tag. "; - //TODO check whether this are all variants (no, auto-stuff is missing). - + $tags=get_tags($text); $this->assertTrue(in_array("@Mike", $tags)); From 509ed2604fe6860b83e02984f8b4a280496a22a8 Mon Sep 17 00:00:00 2001 From: Alexander Kampmann Date: Wed, 14 Mar 2012 12:54:49 +0100 Subject: [PATCH 11/11] splitted tests into several files --- tests/autoname_test.php | 73 +++++++++++++++ tests/contains_attribute_test.php | 51 ++++++++++ tests/expand_acl_test.php | 142 ++++++++++++++++++++++++++++ tests/xss_filter_test.php | 149 +----------------------------- 4 files changed, 269 insertions(+), 146 deletions(-) create mode 100755 tests/autoname_test.php create mode 100755 tests/contains_attribute_test.php create mode 100755 tests/expand_acl_test.php diff --git a/tests/autoname_test.php b/tests/autoname_test.php new file mode 100755 index 0000000000..9dae920ca2 --- /dev/null +++ b/tests/autoname_test.php @@ -0,0 +1,73 @@ +assertNotEquals($autoname1, $autoname2); + } + + /** + *autonames should be random, odd length + */ + public function testAutonameOdd() { + $autoname1=autoname(9); + $autoname2=autoname(9); + + $this->assertNotEquals($autoname1, $autoname2); + } + + /** + * try to fail autonames + */ + public function testAutonameNoLength() { + $autoname1=autoname(0); + $this->assertEquals(0, count($autoname1)); + } + + /** + * try to fail it with invalid input + * + * TODO: What's corect behaviour here? An exception? + */ + public function testAutonameNegativeLength() { + $autoname1=autoname(-23); + $this->assertEquals(0, count($autoname1)); + } + + // public function testAutonameMaxLength() { + // $autoname2=autoname(PHP_INT_MAX); + // $this->assertEquals(PHP_INT_MAX, count($autoname2)); + // } + + /** + * test with a length, that may be too short + */ + public function testAutonameLength1() { + $autoname1=autoname(1); + $this->assertEquals(1, count($autoname1)); + + $autoname2=autoname(1); + $this->assertEquals(1, count($autoname2)); + + $this->assertFalse($autoname1==$autoname2); + } +} \ No newline at end of file diff --git a/tests/contains_attribute_test.php b/tests/contains_attribute_test.php new file mode 100755 index 0000000000..b0bb06acfa --- /dev/null +++ b/tests/contains_attribute_test.php @@ -0,0 +1,51 @@ +assertTrue(attribute_contains($testAttr, "class3")); + $this->assertFalse(attribute_contains($testAttr, "class2")); + } + + /** + * test attribute contains + */ + public function testAttributeContains2() { + $testAttr="class1 not-class2 class3"; + $this->assertTrue(attribute_contains($testAttr, "class3")); + $this->assertFalse(attribute_contains($testAttr, "class2")); + } + + /** + * test with empty input + */ + public function testAttributeContainsEmpty() { + $testAttr=""; + $this->assertFalse(attribute_contains($testAttr, "class2")); + } + + /** + * test input with special chars + */ + public function testAttributeContainsSpecialChars() { + $testAttr="--... %\$ä() /(=?}"; + $this->assertFalse(attribute_contains($testAttr, "class2")); + } +} \ No newline at end of file diff --git a/tests/expand_acl_test.php b/tests/expand_acl_test.php new file mode 100755 index 0000000000..b516a3f14d --- /dev/null +++ b/tests/expand_acl_test.php @@ -0,0 +1,142 @@ +<2><3>'; + $this->assertEquals(array(1, 2, 3), expand_acl($text)); + } + + /** + * test with a big number + */ + public function testExpandAclBigNumber() { + $text='<1><'.PHP_INT_MAX.'><15>'; + $this->assertEquals(array(1, PHP_INT_MAX, 15), expand_acl($text)); + } + + /** + * test with a string in it. + * + * TODO: is this valid input? Otherwise: should there be an exception? + */ + public function testExpandAclString() { + $text="<1><279012>"; + $this->assertEquals(array(1, 279012, 'tt'), expand_acl($text)); + } + + /** + * test with a ' ' in it. + * + * TODO: is this valid input? Otherwise: should there be an exception? + */ + public function testExpandAclSpace() { + $text="<1><279 012><32>"; + $this->assertEquals(array(1, "279 012", "32"), expand_acl($text)); + } + + /** + * test empty input + */ + public function testExpandAclEmpty() { + $text=""; + $this->assertEquals(array(), expand_acl($text)); + } + + /** + * test invalid input, no < at all + * + * TODO: should there be an exception? + */ + public function testExpandAclNoBrackets() { + $text="According to documentation, that's invalid. "; //should be invalid + $this->assertEquals(array(), expand_acl($text)); + } + + /** + * test invalid input, just open < + * + * TODO: should there be an exception? + */ + public function testExpandAclJustOneBracket1() { + $text="assertEquals(array(), expand_acl($text)); + } + + /** + * test invalid input, just close > + * + * TODO: should there be an exception? + */ + public function testExpandAclJustOneBracket2() { + $text="Another invalid> string"; //should be invalid + $this->assertEquals(array(), expand_acl($text)); + } + + /** + * test invalid input, just close > + * + * TODO: should there be an exception? + */ + public function testExpandAclCloseOnly() { + $text="Another> invalid> string>"; //should be invalid + $this->assertEquals(array(), expand_acl($text)); + } + + /** + * test invalid input, just open < + * + * TODO: should there be an exception? + */ + public function testExpandAclOpenOnly() { + $text="assertEquals(array(), expand_acl($text)); + } + + /** + * test invalid input, open and close do not match + * + * TODO: should there be an exception? + */ + public function testExpandAclNoMatching1() { + $text=" invalid "; //should be invalid + $this->assertEquals(array(), expand_acl($text)); + } + + /** + * test invalid input, open and close do not match + * + * TODO: should there be an exception? + */ + public function testExpandAclNoMatching2() { + $text="<1>2><3>"; + $this->assertEquals(array(), expand_acl($text)); + } + + /** + * test invalid input, empty <> + * + * TODO: should there be an exception? Or array(1, 3) + */ + public function testExpandAclEmptyMatch() { + $text="<1><><3>"; + $this->assertEquals(array(), expand_acl($text)); + } +} \ No newline at end of file diff --git a/tests/xss_filter_test.php b/tests/xss_filter_test.php index fe944c2a74..d7dcf0472b 100644 --- a/tests/xss_filter_test.php +++ b/tests/xss_filter_test.php @@ -1,24 +1,16 @@ '; @@ -30,49 +22,6 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $this->assertEquals("<submit type="button" onclick="alert('failed!');" />", $escapedString); } - /** - *autonames should be random, even length - */ - public function testAutonameEven() { - $autoname1=autoname(10); - $autoname2=autoname(10); - - $this->assertNotEquals($autoname1, $autoname2); - } - - /** - *autonames should be random, odd length - */ - public function testAutonameOdd() { - $autoname1=autoname(9); - $autoname2=autoname(9); - - $this->assertNotEquals($autoname1, $autoname2); - } - - /** - * try to fail autonames - */ - public function testAutonameNoLength() { - $autoname1=autoname(0); - $this->assertEquals(0, count($autoname1)); - } - - public function testAutonameNegativeLength() { - $autoname1=autoname(-23); - $this->assertEquals(0, count($autoname1)); - } - - // public function testAutonameMaxLength() { - // $autoname2=autoname(PHP_INT_MAX); - // $this->assertEquals(PHP_INT_MAX, count($autoname2)); - // } - - public function testAutonameLength1() { - $autoname3=autoname(1); - $this->assertEquals(1, count($autoname3)); - } - /** *xmlify and unxmlify */ @@ -87,7 +36,6 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { /** * test hex2bin and reverse */ - public function testHex2Bin() { $this->assertEquals(-3, hex2bin(bin2hex(-3))); $this->assertEquals(0, hex2bin(bin2hex(0))); @@ -95,97 +43,6 @@ class AntiXSSTest extends PHPUnit_Framework_TestCase { $this->assertEquals(PHP_INT_MAX, hex2bin(bin2hex(PHP_INT_MAX))); } - /** - * test expand_acl - */ - public function testExpandAclNormal() { - $text="<1><2><3>"; - $this->assertEquals(array(1, 2, 3), expand_acl($text)); - } - - public function testExpandAclBigNumber() { - $text="<1><279012><15>"; - $this->assertEquals(array(1, 279012, 15), expand_acl($text)); - } - - public function testExpandAclString() { - $text="<1><279012>"; //maybe that's invalid - $this->assertEquals(array(1, 279012, 'tt'), expand_acl($text)); - } - - public function testExpandAclSpace() { - $text="<1><279 012><32>"; //maybe that's invalid - $this->assertEquals(array(1, "279 012", "32"), expand_acl($text)); - } - - public function testExpandAclEmpty() { - $text=""; //maybe that's invalid - $this->assertEquals(array(), expand_acl($text)); - } - - public function testExpandAclNoBrackets() { - $text="According to documentation, that's invalid. "; //should be invalid - $this->assertEquals(array(), expand_acl($text)); - } - - public function testExpandAclJustOneBracket1() { - $text="assertEquals(array(), expand_acl($text)); - } - - public function testExpandAclJustOneBracket2() { - $text="Another invalid> string"; //should be invalid - $this->assertEquals(array(), expand_acl($text)); - } - - public function testExpandAclCloseOnly() { - $text="Another> invalid> string>"; //should be invalid - $this->assertEquals(array(), expand_acl($text)); - } - - public function testExpandAclOpenOnly() { - $text="assertEquals(array(), expand_acl($text)); - } - - public function testExpandAclNoMatching1() { - $text=" invalid "; //should be invalid - $this->assertEquals(array(), expand_acl($text)); - } - - public function testExpandAclNoMatching2() { - $text="<1>2><3>"; - $this->assertEquals(array(), expand_acl($text)); - } - - /** - * test attribute contains - */ - public function testAttributeContains1() { - $testAttr="class1 notclass2 class3"; - $this->assertTrue(attribute_contains($testAttr, "class3")); - $this->assertFalse(attribute_contains($testAttr, "class2")); - } - - /** - * test attribute contains - */ - public function testAttributeContains2() { - $testAttr="class1 not-class2 class3"; - $this->assertTrue(attribute_contains($testAttr, "class3")); - $this->assertFalse(attribute_contains($testAttr, "class2")); - } - - public function testAttributeContainsEmpty() { - $testAttr=""; - $this->assertFalse(attribute_contains($testAttr, "class2")); - } - - public function testAttributeContainsSpecialChars() { - $testAttr="--... %\$ä() /(=?}"; - $this->assertFalse(attribute_contains($testAttr, "class2")); - } - //function qp, quick and dirty?? //get_mentions //get_contact_block, bis Zeile 538