From f309e4037c11197e4392e402992882358e4678c7 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 6 Sep 2013 23:09:18 +1000 Subject: Better and faster basic flood prevention, while merging it into $config['filters']. --- post.php | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'post.php') diff --git a/post.php b/post.php index deebe668..2a5f65c6 100644 --- a/post.php +++ b/post.php @@ -198,7 +198,7 @@ if (isset($_POST['delete'])) { } if ($post['mod'] = isset($_POST['mod']) && $_POST['mod']) { - require 'inc/mod.php'; + require 'inc/mod/auth.php'; if (!$mod) { // Liar. You're not a mod. error($config['error']['notamod']); @@ -428,11 +428,6 @@ if (isset($_POST['delete'])) { wordfilters($post['body']); - // Check for a flood - if (!hasPermission($config['mod']['flood'], $board['uri']) && checkFlood($post)) { - error($config['error']['flood']); - } - $post['body'] = escape_markup_modifiers($post['body']); if ($mod && isset($post['raw']) && $post['raw']) { @@ -468,10 +463,8 @@ if (isset($_POST['delete'])) { } $post['tracked_cites'] = markup($post['body'], true); + - require_once 'inc/filters.php'; - - do_filters($post); if ($post['has_file']) { if (!in_array($post['extension'], $config['allowed_ext']) && !in_array($post['extension'], $config['allowed_ext_files'])) @@ -487,9 +480,17 @@ if (isset($_POST['delete'])) { if (!is_readable($upload)) error($config['error']['nomove']); - $post['filehash'] = $config['file_hash']($upload); + $post['filehash'] = md5_file($upload); $post['filesize'] = filesize($upload); + } + + if (!hasPermission($config['mod']['bypass_filters'], $board['uri'])) { + require_once 'inc/filters.php'; + do_filters($post); + } + + if ($post['has_file']) { if ($is_an_image && $config['ie_mime_type_detection'] !== false) { // Check IE MIME type detection XSS exploit $buffer = file_get_contents($upload, null, null, null, 255); @@ -679,6 +680,8 @@ if (isset($_POST['delete'])) { $post['id'] = $id = post($post); + insertFloodPost($post); + if (isset($post['antispam_hash'])) { incrementSpamHash($post['antispam_hash']); } -- cgit v1.3 From 32c999346f3a4919f527df7465e5989afba6e7bc Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 15 Sep 2013 05:46:08 +1000 Subject: Remove $config['url_regex']; --- inc/config.php | 3 --- inc/functions.php | 2 +- post.php | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'post.php') diff --git a/inc/config.php b/inc/config.php index 90e66a2c..e1929766 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1444,6 +1444,3 @@ // is the absolute maximum, because MySQL cannot handle table names greater than 64 characters. $config['board_regex'] = '[0-9a-zA-Z$_\x{0080}-\x{FFFF}]{1,58}'; - // Regex for URLs. - $config['url_regex'] = '@^(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))$@'; - diff --git a/inc/functions.php b/inc/functions.php index 5a95c851..377607fb 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -94,7 +94,7 @@ function loadConfig() { if (!isset($config['referer_match'])) if (isset($_SERVER['HTTP_HOST'])) { $config['referer_match'] = '/^' . - (preg_match($config['url_regex'], $config['root']) ? '' : + (preg_match('@^https?:@//', $config['root']) ? '' : 'https?:\/\/' . $_SERVER['HTTP_HOST']) . preg_quote($config['root'], '/') . '(' . diff --git a/post.php b/post.php index 2a5f65c6..fc23b47b 100644 --- a/post.php +++ b/post.php @@ -273,7 +273,7 @@ if (isset($_POST['delete'])) { if ($config['allow_upload_by_url'] && isset($_POST['file_url']) && !empty($_POST['file_url'])) { $post['file_url'] = $_POST['file_url']; - if (!preg_match($config['url_regex'], $post['file_url'])) + if (!preg_match('@^https?:@//', $post['file_url'])) error($config['error']['invalidimg']); if (mb_strpos($post['file_url'], '?') !== false) -- cgit v1.3 From 4cd23896559dbbcd0bae5746ee458ece36be7a65 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 15 Sep 2013 05:48:37 +1000 Subject: lol --- inc/functions.php | 2 +- post.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'post.php') diff --git a/inc/functions.php b/inc/functions.php index 377607fb..4cbd8625 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -94,7 +94,7 @@ function loadConfig() { if (!isset($config['referer_match'])) if (isset($_SERVER['HTTP_HOST'])) { $config['referer_match'] = '/^' . - (preg_match('@^https?:@//', $config['root']) ? '' : + (preg_match('@^https?://@', $config['root']) ? '' : 'https?:\/\/' . $_SERVER['HTTP_HOST']) . preg_quote($config['root'], '/') . '(' . diff --git a/post.php b/post.php index fc23b47b..1fe3b35f 100644 --- a/post.php +++ b/post.php @@ -273,7 +273,7 @@ if (isset($_POST['delete'])) { if ($config['allow_upload_by_url'] && isset($_POST['file_url']) && !empty($_POST['file_url'])) { $post['file_url'] = $_POST['file_url']; - if (!preg_match('@^https?:@//', $post['file_url'])) + if (!preg_match('@^https?://@', $post['file_url'])) error($config['error']['invalidimg']); if (mb_strpos($post['file_url'], '?') !== false) -- cgit v1.3 From 00833eeafd6e0f71390504ac10ddf86bbaceb39f Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 15 Sep 2013 14:03:27 +1000 Subject: js/ajax.js: post with ajax --- inc/config.php | 1 + inc/display.php | 8 +++++ js/ajax.js | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ js/quick-reply.js | 9 +++++- post.php | 10 +++++- 5 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 js/ajax.js (limited to 'post.php') diff --git a/inc/config.php b/inc/config.php index e1929766..e6856341 100644 --- a/inc/config.php +++ b/inc/config.php @@ -272,6 +272,7 @@ 'quick-reply', 'page', 'file_url', + 'json_response', ); // Enable reCaptcha to make spam even harder. Rarely necessary. diff --git a/inc/display.php b/inc/display.php index e2646c60..7cd69134 100644 --- a/inc/display.php +++ b/inc/display.php @@ -74,6 +74,14 @@ function error($message, $priority = true, $debug_stuff = false) { $debug_stuff = array_combine(array('SQLSTATE', 'Error code', 'Error message'), $db_error); } + // Is there a reason to disable this? + if (isset($_POST['json_response'])) { + header('Content-Type: text/json; charset=utf-8'); + die(json_encode(array( + 'error' => $message + ))); + } + die(Element('page.html', array( 'config' => $config, 'title' => _('Error'), diff --git a/js/ajax.js b/js/ajax.js new file mode 100644 index 00000000..d29f8fc7 --- /dev/null +++ b/js/ajax.js @@ -0,0 +1,93 @@ +/* + * ajax.js + * https://github.com/savetheinternet/Tinyboard/blob/master/js/ajax.js + * + * Released under the MIT license + * Copyright (c) 2013 Michael Save + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/ajax.js'; + * + */ + +$(window).ready(function() { + var setup_form = function($form) { + $form.submit(function() { + var form = this; + var submit_txt = $(this).find('input[type="submit"]').val(); + if (typeof FormData == 'undefined') + return true; + + var formData = new FormData(this); + formData.append('json_response', '1'); + + var updateProgress = function(e) { + $(form).find('input[type="submit"]').val(_('Posting... (#%)').replace('#', Math.round(e.position / e.total * 100))); + }; + + $.ajax({ + url: this.action, + type: 'POST', + xhr: function() { + var xhr = $.ajaxSettings.xhr(); + if(xhr.upload) { + xhr.upload.addEventListener('progress', updateProgress, false); + } + return xhr; + }, + success: function(post_response) { + if (post_response.error) { + alert(post_response.error); + $(form).find('input[type="submit"]').val(submit_txt); + $(form).find('input[type="submit"]').removeAttr('disabled'); + } else if (post_response.redirect && post_response.id) { + $.ajax({ + url: post_response.redirect, + success: function(data) { + console.log(data); + $(data).find('div.post.reply').each(function() { + var id = $(this).attr('id'); + if($('#' + id).length == 0) { + $(this).insertAfter($('div.post:last').next()).after('
'); + $(document).trigger('new_post', this); + } + }); + highlightReply(post_response.id); + document.location = '#' + post_response.id; + + $(form).find('input[type="submit"]').val(submit_txt); + $(form).find('input[type="submit"]').removeAttr('disabled'); + } + }, 'html'); + + $(form).find('input[type="submit"]').val('Posted...'); + } else { + alert(_('An unknown error occured when posting!')); + $(form).find('input[type="submit"]').val(submit_txt); + $(form).find('input[type="submit"]').removeAttr('disabled'); + } + }, + error: function(xhr, status, er) { + // An error occured + // TODO + console.log('Error'); + }, + // Form data + data: formData, + cache: false, + contentType: false, + processData: false + }, 'html'); + + $(form).find('input[type="submit"]').val(_('Posting...')); + $(form).find('input[type="submit"]').attr('disabled', true); + + return false; + }); + }; + setup_form($('form[name="post"]')); + $(window).on('quick-reply', function(e, quickForm) { + setup_form($('form#quick-reply')); + }); +}); diff --git a/js/quick-reply.js b/js/quick-reply.js index 824286f6..5f81f51e 100644 --- a/js/quick-reply.js +++ b/js/quick-reply.js @@ -123,6 +123,9 @@ var show_quick_reply = function(){ } // Move anti-spam nonsense and remove + $th.contents().filter(function() { + return this.nodeType == 3; // Node.TEXT_NODE + }).remove(); $th.contents().appendTo($dummyStuff); $th.remove(); @@ -180,7 +183,9 @@ var show_quick_reply = function(){ }); $postForm.find('textarea[name="body"]').removeAttr('id').removeAttr('cols').attr('placeholder', _('Comment')); - + + $postForm.find('textarea:not([name="body"]),input[type="hidden"]').appendTo($dummyStuff); + $postForm.find('br').remove(); $postForm.find('table').prepend('' + _('Quick Reply') + ''); @@ -232,6 +237,8 @@ var show_quick_reply = function(){ } $postForm.show(); + $(window).trigger('quick-reply'); + $origPostForm = $('form[name="post"]'); $(window).ready(function() { diff --git a/post.php b/post.php index 1fe3b35f..0bc26f46 100644 --- a/post.php +++ b/post.php @@ -743,7 +743,15 @@ if (isset($_POST['delete'])) { else rebuildThemes('post', $board['uri']); - header('Location: ' . $redirect, true, $config['redirect_http']); + if (!isset($_POST['json_response'])) { + header('Location: ' . $redirect, true, $config['redirect_http']); + } else { + header('Content-Type: text/json; charset=utf-8'); + echo json_encode(array( + 'redirect' => $redirect, + 'id' => $id + )); + } } else { if (!file_exists($config['has_installed'])) { header('Location: install.php', true, $config['redirect_http']); -- cgit v1.3 From 30fb025eef81421b1dbb8b0f31d5f4d7360e1e36 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 15 Sep 2013 20:15:17 +1000 Subject: ; --- js/ajax.js | 3 +-- post.php | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'post.php') diff --git a/js/ajax.js b/js/ajax.js index e3bb2f88..a063890b 100644 --- a/js/ajax.js +++ b/js/ajax.js @@ -75,7 +75,7 @@ $(window).ready(function() { processData: false }, 'html'); } - $(form).find('input[type="submit"]').val('Posted...'); + $(form).find('input[type="submit"]').val(_('Posted...')); } else { alert(_('An unknown error occured when posting!')); $(form).find('input[type="submit"]').val(submit_txt); @@ -96,7 +96,6 @@ $(window).ready(function() { }); $(form).submit(); }, - // Form data data: formData, cache: false, contentType: false, diff --git a/post.php b/post.php index 0bc26f46..026e2b2d 100644 --- a/post.php +++ b/post.php @@ -1,5 +1,7 @@ Date: Mon, 16 Sep 2013 04:42:13 +1000 Subject: ajax-post-controls.js --- js/ajax-post-controls.js | 77 +++++++++++++++++++++++++++++++++++++++++++++++ js/quick-post-controls.js | 2 ++ post.php | 17 ++++++++--- 3 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 js/ajax-post-controls.js (limited to 'post.php') diff --git a/js/ajax-post-controls.js b/js/ajax-post-controls.js new file mode 100644 index 00000000..4671e82e --- /dev/null +++ b/js/ajax-post-controls.js @@ -0,0 +1,77 @@ +/* + * ajax-post-controls.js + * https://github.com/savetheinternet/Tinyboard/blob/master/js/ajax-post-controls.js + * + * Released under the MIT license + * Copyright (c) 2013 Michael Save + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/ajax-post-controls.js'; + * + */ + +$(window).ready(function() { + var do_not_ajax = false; + + var setup_form = function($form) { + $form.find('input[type="submit"]').click(function() { + $form.data('submit-btn', this); + });; + $form.submit(function(e) { + if (!$(this).data('submit-btn')) + return true; + if (do_not_ajax) + return true; + if (window.FormData === undefined) + return true; + + var form = this; + + var formData = new FormData(this); + formData.append('json_response', '1'); + formData.append($($(form).data('submit-btn')).attr('name'), $($(form).data('submit-btn')).val()); + + $.ajax({ + url: this.action, + type: 'POST', + success: function(post_response) { + if (post_response.error) { + alert(post_response.error); + } else if (post_response.success) { + if ($($(form).data('submit-btn')).attr('name') == 'report') { + alert(_('Reported post(s).')); + if ($(form).hasClass('post-actions')) { + $(form).parent().find('input[type="checkbox"].delete').click(); + } else { + $(form).find('input[name="reason"]').val(''); + } + } else { + window.location.reload(); + } + } else { + alert(_('An unknown error occured!')); + } + $($(form).data('submit-btn')).val($($(form).data('submit-btn')).data('orig-val')).removeAttr('disabled'); + }, + error: function(xhr, status, er) { + // An error occured + // TODO + alert(_('Something went wrong... An unknown error occured!')); + }, + data: formData, + cache: false, + contentType: false, + processData: false + }, 'json'); + + $($(form).data('submit-btn')).attr('disabled', true).data('orig-val', $($(form).data('submit-btn')).val()).val(_('Working...')); + + return false; + }); + }; + setup_form($('form[name="postcontrols"]')); + $(window).on('quick-post-controls', function(e, form) { + setup_form($(form)); + }); +}); diff --git a/js/quick-post-controls.js b/js/quick-post-controls.js index 1cbc0711..efce3371 100644 --- a/js/quick-post-controls.js +++ b/js/quick-post-controls.js @@ -63,6 +63,8 @@ $(document).ready(function(){ post_form.appendTo($(this).parent().parent()); //post_form.insertBefore($(this)); } + + $(window).trigger('quick-post-controls', post_form); } else { var elm = $(this).parent().parent().find('form'); diff --git a/post.php b/post.php index 026e2b2d..8bc7b51d 100644 --- a/post.php +++ b/post.php @@ -58,7 +58,7 @@ if (isset($_POST['delete'])) { if ($password != '' && $post['password'] != $password) error($config['error']['invalidpassword']); - if ($post['time'] >= time() - $config['delete_time']) { + if ($post['time'] > time() - $config['delete_time']) { error(sprintf($config['error']['delete_too_soon'], until($post['time'] + $config['delete_time']))); } @@ -84,8 +84,12 @@ if (isset($_POST['delete'])) { $is_mod = isset($_POST['mod']) && $_POST['mod']; $root = $is_mod ? $config['root'] . $config['file_mod'] . '?/' : $config['root']; - header('Location: ' . $root . $board['dir'] . $config['file_index'], true, $config['redirect_http']); - + if (!isset($_POST['json_response'])) { + header('Location: ' . $root . $board['dir'] . $config['file_index'], true, $config['redirect_http']); + } else { + header('Content-Type: text/json'); + echo json_encode(array('success' => true)); + } } elseif (isset($_POST['report'])) { if (!isset($_POST['board'], $_POST['password'], $_POST['reason'])) error($config['error']['bot']); @@ -139,7 +143,12 @@ if (isset($_POST['delete'])) { $is_mod = isset($_POST['mod']) && $_POST['mod']; $root = $is_mod ? $config['root'] . $config['file_mod'] . '?/' : $config['root']; - header('Location: ' . $root . $board['dir'] . $config['file_index'], true, $config['redirect_http']); + if (!isset($_POST['json_response'])) { + header('Location: ' . $root . $board['dir'] . $config['file_index'], true, $config['redirect_http']); + } else { + header('Content-Type: text/json'); + echo json_encode(array('success' => true)); + } } elseif (isset($_POST['post'])) { if (!isset($_POST['body'], $_POST['board'])) error($config['error']['bot']); -- cgit v1.3