Ссылка NullReferenceException или Object, не установленная на экземпляр объекта, возникает, когда объект класса, который вы пытаетесь использовать, не создается. Например:
Предположим, что у вас есть класс с именем Student.
public class Student
{
private string FirstName;
private string LastName;
public string GetFullName()
{
return FirstName + LastName;
}
}
Теперь рассмотрим другой класс, в котором вы пытаетесь получить полное имя учащегося.
public class StudentInfo
{
public string GetStudentName()
{
Student s;
string fullname = s.GetFullName();
return fullname;
}
}
Как видно из вышеприведенного кода, оператор Student s - объявляет только переменную типа Student, обратите внимание, что класс Student не создается в этой точке. Следовательно, когда выполняется выполнение инструкции s.GetFullName (), она выкинет исключение NullReferenceException.
Никогда не используйте escape()
. HTML-кодирование не имеет никакого отношения. Это больше похоже на кодирование URL, но это даже не так. Это странная нестандартная кодировка, доступная только в JavaScript.
Если вы хотите кодировщик HTML, вам придется писать его самостоятельно, поскольку JavaScript не дает вам одного. Например:
function encodeHTML(s) {
return s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}
Однако, пока этого достаточно, чтобы разместить user_id
в таких местах, как input value
, этого недостаточно для id
, поскольку идентификаторы могут использовать только ограниченный набор символов. (И %
не входит в их число, поэтому escape()
или даже encodeURIComponent()
не годится.)
Вы можете придумать свою собственную схему кодирования, чтобы поместить любые символы в идентификатор, например:
function encodeID(s) {
if (s==='') return '_';
return s.replace(/[^a-zA-Z0-9.-]/g, function(match) {
return '_'+match[0].charCodeAt(0).toString(16)+'_';
});
}
Но у вас все еще есть проблема, если один и тот же user_id
происходит дважды. И, честно говоря, все дело в том, чтобы бросить вокруг строк HTML, как правило, плохая идея. Вместо этого используйте методы DOM и сохраняйте ссылки JavaScript на каждый элемент, поэтому вам не нужно продолжать звонить getElementById
или беспокоиться о том, как вставляются произвольные строки в идентификаторы.
например.:
function addChut(user_id) {
var log= document.createElement('div');
log.className= 'log';
var textarea= document.createElement('textarea');
var input= document.createElement('input');
input.value= user_id;
input.readonly= True;
var button= document.createElement('input');
button.type= 'button';
button.value= 'Message';
var chut= document.createElement('div');
chut.className= 'chut';
chut.appendChild(log);
chut.appendChild(textarea);
chut.appendChild(input);
chut.appendChild(button);
document.getElementById('chuts').appendChild(chut);
button.onclick= function() {
alert('Send '+textarea.value+' to '+user_id);
};
return chut;
}
Вы также можете использовать функцию удобства или структуру JS, чтобы сократить длительность вызовов, созданных при создании-добавлении.
ETA:
Я использую jQuery в качестве рамки
blockquote>ОК, затем рассмотрим ярлыки создания jQuery 1.4, например ::
var log= $('<div>', {className: 'log'}); var input= $('<input>', {readOnly: true, val: user_id}); ...
Проблема, с которой я столкнулся сейчас, заключается в том, что я использую JSONP для добавления элементов и событий на страницу, поэтому я не могу знать, существуют ли эти элементы или нет, прежде чем показывать сообщение.
blockquote>Вы может сохранить поиск
user_id
к узлам элемента (или объектам-оболочкам) в JavaScript, чтобы сохранить эту информацию в самой DOM, где символы, которые могут попасть вid
, ограничены.var chut_lookup= {}; ... function getChut(user_id) { var key= '_map_'+user_id; if (key in chut_lookup) return chut_lookup[key]; return chut_lookup[key]= addChut(user_id); }
(Префикс
_map_
связан с тем, что объекты JavaScript не имеют довольно работают как отображение произвольных строк. Пустая строка и в IE некоторые именаObject
членов путают ее.)
Вы можете использовать простое регулярное выражение, чтобы утверждать, что идентификатор содержит только допустимые символы:
if(id.match(/^[0-9a-zA-Z]{1,16}$/)){
//The id is fine
}
else{
//The id is illegal
}
В моем примере допускаются только буквенно-цифровые символы и строки длиной от 1 до 16, вы должны измените его в соответствии с типом используемых вами идентификаторов.
Кстати, в строке 6 свойство value отсутствует пара кавычек, что легко сделать при цитировании на двух уровнях.
Я не вижу ваш фактический поток данных, в зависимости от контекста эта проверка может вообще не понадобиться, или ее может быть недостаточно. Чтобы сделать правильный обзор безопасности, нам понадобится дополнительная информация.
В целом, о встроенных средствах спасения или дезинфекции, не доверяйте им слепо. Вам нужно точно знать, что они делают, и вам нужно установить, что это на самом деле то, что вам нужно. Если это не то, что вам нужно, код, свой собственный, в большинстве случаев простое белое правило, подобное тому, которое я дал вам, работает отлично.
Поскольку текст, который вы экранируете, будет отображаться в атрибуте HTML, вы должны обязательно избегать не только HTML-объектов, но и атрибутов HTML:
var ESC_MAP = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
function escapeHTML(s, forAttribute) {
return s.replace(forAttribute ? /[&<>'"]/g : /[&<>]/g, function(c) {
return ESC_MAP[c];
});
}
Затем ваш код экранирования станет var user_id = escapeHTML(id, true)
.
Для получения дополнительной информации см. Foolproof HTML escaping в Javascript .
Другим подходом, который мне нравится, является использование собственных возможностей DOM: http://shebang.brandonmintern.com/foolproof-html-escaping-in-javascript
При использовании пользовательских данных в атрибутах HTML вам необходимо принять дополнительные меры предосторожности. Поскольку атрибуты имеют гораздо больше векторов атак, чем вывод внутри HTML-тегов.
Единственный способ избежать атак XSS - это кодировать все, кроме буквенно-цифровых символов. Удалите все символы с значениями ASCII менее 256 с помощью & amp; #xHH; формат. Что, к сожалению, может вызвать проблемы в вашем сценарии, если вы используете классы CSS и javascript для извлечения этих элементов.
OWASP имеет хорошее описание того, как уменьшить атрибут HTML XSS:
Вы также можете использовать это:
function sanitarize(string) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"/": '/',
};
const reg = /[&<>"'/]/ig;
return string.replace(reg, (match)=>(map[match]));
}
Документация OWASP предполагает сопоставление: https://www.owasp.org/index.php/XSS_ (Cross_Site_Scripting) _Prevention_Cheat_Sheet