From c677013b9376a3054750badf97f7d1e73aa37735 Mon Sep 17 00:00:00 2001 From: Sebastien SAUVAGE Date: Tue, 24 Sep 2013 22:39:40 +0200 Subject: [PATCH 01/11] Added nb=all to get all links in RSS/ATOM feed. --- index.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index d9181b65..396b97fc 100644 --- a/index.php +++ b/index.php @@ -898,7 +898,11 @@ function showRSS() if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); else $linksToDisplay = $LINKSDB; - $nblinksToDisplay = !empty($_GET['nb']) ? max($_GET['nb'] + 0, 1) : 50; + $nblinksToDisplay = 50; // Number of links to display. + if (!empty($_GET['nb'])) // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links. + { + $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max($_GET['nb']+0,1) ; + } $pageaddr=htmlspecialchars(indexUrl()); echo ''; @@ -969,7 +973,11 @@ function showATOM() if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); else $linksToDisplay = $LINKSDB; - $nblinksToDisplay = !empty($_GET['nb']) ? max($_GET['nb'] + 0, 1) : 50; + $nblinksToDisplay = 50; // Number of links to display. + if (!empty($_GET['nb'])) // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links. + { + $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max($_GET['nb']+0,1) ; + } $pageaddr=htmlspecialchars(indexUrl()); $latestDate = ''; From 58a8f4cab466446499cdda0cce000a82bd486105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20SAUVAGE?= Date: Wed, 25 Sep 2013 10:41:31 +0200 Subject: [PATCH 02/11] Default example private link changed Default example private link changed from pastebin to ZeroBin. --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index 396b97fc..23a6294c 100644 --- a/index.php +++ b/index.php @@ -740,7 +740,7 @@ private function checkdb() // Check if db directory and file exists. $this->links = array(); $link = array('title'=>'Shaarli - sebsauvage.net','url'=>'http://sebsauvage.net/wiki/doku.php?id=php:shaarli','description'=>'Welcome to Shaarli ! This is a bookmark. To edit or delete me, you must first login.','private'=>0,'linkdate'=>'20110914_190000','tags'=>'opensource software'); $this->links[$link['linkdate']] = $link; - $link = array('title'=>'My secret stuff... - Pastebin.com','url'=>'http://pastebin.com/smCEEeSn','description'=>'SShhhh!! I\'m a private link only YOU can see. You can delete me too.','private'=>1,'linkdate'=>'20110914_074522','tags'=>'secretstuff'); + $link = array('title'=>'My secret stuff... - Pastebin.com','url'=>'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=','description'=>'SShhhh!! I\'m a private link only YOU can see. You can delete me too.','private'=>1,'linkdate'=>'20110914_074522','tags'=>'secretstuff'); $this->links[$link['linkdate']] = $link; file_put_contents($GLOBALS['config']['DATASTORE'], PHPPREFIX.base64_encode(gzdeflate(serialize($this->links))).PHPSUFFIX); // Write database to disk } From 83cff11de5fac834ab224ed658b821676a6d54a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20SAUVAGE?= Date: Wed, 25 Sep 2013 14:57:27 +0200 Subject: [PATCH 03/11] Added javascript QR-Code library --- inc/qr.min.js | Bin 0 -> 11799 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 inc/qr.min.js diff --git a/inc/qr.min.js b/inc/qr.min.js new file mode 100644 index 0000000000000000000000000000000000000000..663ce9303316fee88cea7976ea7ad443d493545d GIT binary patch literal 11799 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 Date: Wed, 25 Sep 2013 14:58:47 +0200 Subject: [PATCH 04/11] Changed QR-Code CSS (selector and attributes) --- inc/shaarli.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/inc/shaarli.css b/inc/shaarli.css index 50839848..52a48208 100644 --- a/inc/shaarli.css +++ b/inc/shaarli.css @@ -316,7 +316,8 @@ text-shadow:2px 2px 1px #000000; background: #ffffff; } -div.qrcode { +div#permalinkQrcode { +padding:20px; width:220px; height:220px; background-color: #ffffff; @@ -465,4 +466,4 @@ div.dailyEntryDescription { font-size:10pt; } } /* Highlight search results */ -.highlight { background-color: #FFFF33; } \ No newline at end of file +.highlight { background-color: #FFFF33; } From af77b2fd9a574ba03b309ea0799946fabf37c7d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20SAUVAGE?= Date: Wed, 25 Sep 2013 15:17:09 +0200 Subject: [PATCH 05/11] New QR-Code generation code * QR-Code generation now uses a client-side javascript library instead of an external service. This is better for user privacy. * Library used is http://neocotic.com/qr.js/ (11 kb). * jQuery is no longer used to display QR-Code (this is a first step in removing jQuery entirely). * This library is loaded *only* if the QR-Code icon is clicked. * If javascript is disabled, it will fallback to the external service. * External service was changed from "invx.com" to "qrfree.kaywa.com" because invx has become bloated. By loading the javascript library *only* if the icon is clicked, it will prevent the 11 kb lib to be loaded in every page. --- tpl/linklist.html | 80 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/tpl/linklist.html b/tpl/linklist.html index 37ffeb64..bce3fa9f 100644 --- a/tpl/linklist.html +++ b/tpl/linklist.html @@ -3,11 +3,11 @@ {include="includes"} {include="page.footer"} +{if="($GLOBALS['config']['OPEN_SHAARLI'] || isLoggedIn()) && empty($GLOBALS['disablejquery'])"} + +{/if} \ No newline at end of file diff --git a/tpl/includes.html b/tpl/includes.html index e0ad00d5..2b61f1e1 100644 --- a/tpl/includes.html +++ b/tpl/includes.html @@ -7,4 +7,3 @@ {if condition="is_file('inc/user.css')"}{/if} -{if="empty($GLOBALS['disablejquery'])"}{/if} diff --git a/tpl/linklist.html b/tpl/linklist.html index bce3fa9f..ddc38cb0 100644 --- a/tpl/linklist.html +++ b/tpl/linklist.html @@ -68,7 +68,6 @@ {include="page.footer"} {/if} - -{if="($GLOBALS['config']['OPEN_SHAARLI'] || isLoggedIn()) && empty($GLOBALS['disablejquery'])"} - -{/if} - -{if="empty($GLOBALS['disablejquery']) && isset($_GET['searchterm'])"} - - -{/if} \ No newline at end of file diff --git a/tpl/picwall.html b/tpl/picwall.html index 631e0866..b78e2609 100644 --- a/tpl/picwall.html +++ b/tpl/picwall.html @@ -2,7 +2,9 @@ {include="includes"} {if="empty($GLOBALS['disablejquery'])"} - + + + {/if} From 2d20481e45ab598dbe46d0a1cceb56de770b387e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20SAUVAGE?= Date: Thu, 26 Sep 2013 15:17:43 +0200 Subject: [PATCH 07/11] Update README.md --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8f3c479b..cff718cf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ ![Shaarli logo](http://sebsauvage.net/wiki/lib/exe/fetch.php?media=php:php_shaarli:php_shaarli_logo_inkscape_w600_transp-nq8.png) -Shaarli -The personal, minimalist, super-fast, no-database delicious clone. +Shaarli, the personal, minimalist, super-fast, no-database delicious clone. You want to share the links you discover ? Shaarli is a minimalist delicious clone you can install on your own website. It is designed to be personal (single-user), fast and handy. @@ -10,36 +9,37 @@ It is designed to be personal (single-user), fast and handy. Features: * Minimalist design (simple is beautiful) - * FAST + * **FAST** * Dead-simple installation: Drop the files, open the page. No database required. * Easy to use: Single button in your browser to bookmark a page * Save url, title, description (unlimited size). Classify links with tags (with autocomplete) * Tag renaming, merging and deletion. * Automatic thumbnails for various services (imgur, imageshack.us, flickr, youtube, vimeo, dailymotion…) - * Automatic conversion of URLs to clickable links in descriptions. Support for http/ftp/file/apt protocols. + * Automatic conversion of URLs to clickable links in descriptions. Support for http/ftp/file/apt/magnet protocols. * Save links as public or private * 1-clic access to your private links/notes * Browse links by page, filter by tag or use the full text search engine * Permalinks (with QR-Code) for easy reference + * RSS and ATOM feeds (which can be filtered by tag or text search) * Tag cloud * Picture wall (which can be filtered by tag or text search) * “Links of the day” Newspaper-like digest, browsable by day. * “Daily” RSS feed: Get each day a digest of all new links. - * RSS and ATOM feeds (which can be filtered by tag or text search) - * PubSubHubbub protocol support + * [PubSubHubbub](https://code.google.com/p/pubsubhubbub/) protocol support * Easy backup (Data stored in a single file) * Compact storage (1315 links stored in 150 kb) * Mobile browsers support + * Also works with javascript disabled * Can import/export Netscape bookmarks (for import/export from/to Firefox, Opera, Chrome, Delicious…) - * Automatic ban of IP address upon too many failed logins - * Protected against XSRF, session cookie hijacking. + * Brute force protected login form + * Protected against [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery), session cookie hijacking. * Automatic removal of annoying FeedBurner/Google FeedProxy parameters in URL (?utm_source…) * Shaarli is a bookmarking application, but you can use it for micro-blogging (like Twitter), a pastebin, an online notepad, a snippet repository, etc. * You will be automatically notified by a discreet popup if a new version is available - * Pages are easy to customize (using simple RainTPL templates) + * Pages are easy to customize (using CSS and simple RainTPL templates) -Requires php 5.1 (php 5.2 required for autocomplete.) +Requires php 5.1 More information on the project page: http://sebsauvage.net/wiki/doku.php?id=php:shaarli From 7b2186a63e2c788f1f2622779c5a1c341117eac1 Mon Sep 17 00:00:00 2001 From: Sebastien SAUVAGE Date: Fri, 27 Sep 2013 17:08:31 +0200 Subject: [PATCH 08/11] Corrected field focus in bookmarklet Focus was not properly given to description field when it's empty. --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index 23a6294c..0465a4e5 100644 --- a/index.php +++ b/index.php @@ -1548,7 +1548,7 @@ function renderPage() $link_is_new = true; // This is a new link $linkdate = strval(date('Ymd_His')); $title = (empty($_GET['title']) ? '' : $_GET['title'] ); // Get title if it was provided in URL (by the bookmarklet). - $description = (empty($_GET['description']) ? '' : $_GET['description'] )."\n"; // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] + $description = (empty($_GET['description']) ? '' : $_GET['description']); // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] $tags = (empty($_GET['tags']) ? '' : $_GET['tags'] ); // Get tags if it was provided in URL $private = (!empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0); // Get private if it was provided in URL if (($url!='') && parse_url($url,PHP_URL_SCHEME)=='') $url = 'http://'.$url; From c002ca9c6ba1d40cda342ca85fb48acda39d7e52 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 10 Nov 2013 22:50:34 +0100 Subject: [PATCH 09/11] smallHash: simplified and improved performance Unchanged behaviour --- index.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/index.php b/index.php index 0465a4e5..24fbe436 100644 --- a/index.php +++ b/index.php @@ -221,7 +221,7 @@ function nl2br_escaped($html) return str_replace('>','>',str_replace('<','<',nl2br($html))); } -/* Returns the small hash of a string +/* Returns the small hash of a string, using RFC 4648 base64url format eg. smallHash('20111006_131924') --> yZH23w Small hashes: - are unique (well, as unique as crc32, at last) @@ -233,10 +233,7 @@ function nl2br_escaped($html) function smallHash($text) { $t = rtrim(base64_encode(hash('crc32',$text,true)),'='); - $t = str_replace('+','-',$t); // Get rid of characters which need encoding in URLs. - $t = str_replace('/','_',$t); - $t = str_replace('=','@',$t); - return $t; + return strtr($t, '+/', '-_'); } // In a string, converts urls to clickable links. From 53da201749f8f362323ef278bf338f1d9f7a925a Mon Sep 17 00:00:00 2001 From: Sebastien SAUVAGE Date: Fri, 29 Nov 2013 21:53:20 +0100 Subject: [PATCH 10/11] XSS flaw correction Closes issue https://github.com/sebsauvage/Shaarli/issues/134 --- index.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.php b/index.php index 0465a4e5..884b2afd 100644 --- a/index.php +++ b/index.php @@ -942,7 +942,7 @@ function showRSS() echo ''."\n\n"; $i++; } - echo ''; + echo ''; $cache->cache(ob_get_contents()); ob_end_flush(); @@ -1027,7 +1027,7 @@ function showATOM() $feed.=''.htmlspecialchars($pageaddr).''.htmlspecialchars($pageaddr).''; $feed.=''.htmlspecialchars($pageaddr).''."\n\n"; // Yes, I know I should use a real IRI (RFC3987), but the site URL will do. $feed.=$entries; - $feed.=''; + $feed.=''; echo $feed; $cache->cache(ob_get_contents()); @@ -1104,7 +1104,7 @@ function showDailyRSS() echo ''."\n\n\n"; } - echo ''; + echo ''; $cache->cache(ob_get_contents()); ob_end_flush(); @@ -1747,11 +1747,11 @@ function importFile() } $LINKSDB->savedb(); - echo ''; + echo ''; } else { - echo ''; + echo ''; } } From 067e66acfee19019ea3c1efa7f4ea305259bbd74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20SAUVAGE?= Date: Wed, 4 Dec 2013 13:55:42 +0100 Subject: [PATCH 11/11] Corrected overlapping tags --- inc/shaarli.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/shaarli.css b/inc/shaarli.css index 52a48208..36daa51c 100644 --- a/inc/shaarli.css +++ b/inc/shaarli.css @@ -239,7 +239,7 @@ cursor:pointer; .linkdescription { color:#000; margin-top:0; margin-bottom:12px; font-weight:normal; max-height:400px; overflow:auto; } .linkdescription a { text-decoration: none; color:#3465A4; } .linkdescription a:hover { color:#F57900; } -.linktaglist { padding-top:10px;} +.linktaglist { padding-top:10px; line-height:200%;} .linktag { font-size:9pt;