mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-26 10:32:56 +01:00
XML: complete merge from 1.4.2
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
#include "winconfig.h"
|
||||
#elif defined(MACOS_CLASSIC)
|
||||
#include "macconfig.h"
|
||||
#elif defined(__amigaos4__)
|
||||
#elif defined(__amigaos__)
|
||||
#include "amigaconfig.h"
|
||||
#elif defined(__WATCOMC__)
|
||||
#include "watcomconfig.h"
|
||||
@@ -327,15 +327,15 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
|
||||
static enum XML_Error
|
||||
initializeEncoding(XML_Parser parser);
|
||||
static enum XML_Error
|
||||
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
|
||||
const char *end, int tok, const char *next, const char **nextPtr,
|
||||
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
|
||||
const char *end, int tok, const char *next, const char **nextPtr,
|
||||
XML_Bool haveMore);
|
||||
static enum XML_Error
|
||||
processInternalEntity(XML_Parser parser, ENTITY *entity,
|
||||
processInternalEntity(XML_Parser parser, ENTITY *entity,
|
||||
XML_Bool betweenDecl);
|
||||
static enum XML_Error
|
||||
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
|
||||
const char *start, const char *end, const char **endPtr,
|
||||
const char *start, const char *end, const char **endPtr,
|
||||
XML_Bool haveMore);
|
||||
static enum XML_Error
|
||||
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
|
||||
@@ -353,7 +353,7 @@ static enum XML_Error
|
||||
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
|
||||
const XML_Char *uri, BINDING **bindingsPtr);
|
||||
static int
|
||||
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
|
||||
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
|
||||
XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
|
||||
static enum XML_Error
|
||||
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
|
||||
@@ -670,7 +670,7 @@ XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
|
||||
|
||||
static const XML_Char implicitContext[] = {
|
||||
ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
|
||||
ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
|
||||
ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
|
||||
ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
|
||||
ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
|
||||
ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
|
||||
@@ -1459,7 +1459,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
|
||||
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
|
||||
positionPtr = bufferPtr;
|
||||
return XML_STATUS_SUSPENDED;
|
||||
case XML_INITIALIZED:
|
||||
case XML_INITIALIZED:
|
||||
case XML_PARSING:
|
||||
ps_parsing = XML_FINISHED;
|
||||
/* fall through */
|
||||
@@ -1512,16 +1512,12 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
|
||||
? (char *)MALLOC(len * 2)
|
||||
: (char *)REALLOC(buffer, len * 2));
|
||||
if (temp == NULL) {
|
||||
errorCode = XML_ERROR_NO_MEMORY;
|
||||
return XML_STATUS_ERROR;
|
||||
}
|
||||
buffer = temp;
|
||||
if (!buffer) {
|
||||
errorCode = XML_ERROR_NO_MEMORY;
|
||||
eventPtr = eventEndPtr = NULL;
|
||||
processor = errorProcessor;
|
||||
return XML_STATUS_ERROR;
|
||||
}
|
||||
buffer = temp;
|
||||
bufferLim = buffer + len * 2;
|
||||
}
|
||||
memcpy(buffer, end, nLeftOver);
|
||||
@@ -1582,7 +1578,7 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
|
||||
case XML_SUSPENDED:
|
||||
result = XML_STATUS_SUSPENDED;
|
||||
break;
|
||||
case XML_INITIALIZED:
|
||||
case XML_INITIALIZED:
|
||||
case XML_PARSING:
|
||||
if (isFinal) {
|
||||
ps_parsing = XML_FINISHED;
|
||||
@@ -1672,6 +1668,8 @@ XML_GetBuffer(XML_Parser parser, int len)
|
||||
bufferPtr = buffer = newBuf;
|
||||
#endif /* not defined XML_CONTEXT_BYTES */
|
||||
}
|
||||
eventPtr = eventEndPtr = NULL;
|
||||
positionPtr = NULL;
|
||||
}
|
||||
return bufferEnd;
|
||||
}
|
||||
@@ -1729,7 +1727,7 @@ XML_ResumeParser(XML_Parser parser)
|
||||
case XML_SUSPENDED:
|
||||
result = XML_STATUS_SUSPENDED;
|
||||
break;
|
||||
case XML_INITIALIZED:
|
||||
case XML_INITIALIZED:
|
||||
case XML_PARSING:
|
||||
if (ps_finalBuffer) {
|
||||
ps_parsing = XML_FINISHED;
|
||||
@@ -1956,7 +1954,7 @@ XML_GetFeatureList(void)
|
||||
#endif
|
||||
#ifdef XML_LARGE_SIZE
|
||||
{XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
|
||||
#endif
|
||||
#endif
|
||||
{XML_FEATURE_END, NULL, 0}
|
||||
};
|
||||
|
||||
@@ -2019,7 +2017,7 @@ contentProcessor(XML_Parser parser,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
enum XML_Error result = doContent(parser, 0, encoding, start, end,
|
||||
enum XML_Error result = doContent(parser, 0, encoding, start, end,
|
||||
endPtr, (XML_Bool)!ps_finalBuffer);
|
||||
if (result == XML_ERROR_NONE) {
|
||||
if (!storeRawNames(parser))
|
||||
@@ -2101,7 +2099,7 @@ externalEntityInitProcessor3(XML_Parser parser,
|
||||
if (result != XML_ERROR_NONE)
|
||||
return result;
|
||||
switch (ps_parsing) {
|
||||
case XML_SUSPENDED:
|
||||
case XML_SUSPENDED:
|
||||
*endPtr = next;
|
||||
return XML_ERROR_NONE;
|
||||
case XML_FINISHED:
|
||||
@@ -2135,7 +2133,7 @@ externalEntityContentProcessor(XML_Parser parser,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
enum XML_Error result = doContent(parser, 1, encoding, start, end,
|
||||
enum XML_Error result = doContent(parser, 1, encoding, start, end,
|
||||
endPtr, (XML_Bool)!ps_finalBuffer);
|
||||
if (result == XML_ERROR_NONE) {
|
||||
if (!storeRawNames(parser))
|
||||
@@ -2154,7 +2152,7 @@ doContent(XML_Parser parser,
|
||||
XML_Bool haveMore)
|
||||
{
|
||||
/* save one level of indirection */
|
||||
DTD * const dtd = _dtd;
|
||||
DTD * const dtd = _dtd;
|
||||
|
||||
const char **eventPP;
|
||||
const char **eventEndPP;
|
||||
@@ -2185,8 +2183,8 @@ doContent(XML_Parser parser,
|
||||
}
|
||||
else if (defaultHandler)
|
||||
reportDefault(parser, enc, s, end);
|
||||
/* We are at the end of the final buffer, should we check for
|
||||
XML_SUSPENDED, XML_FINISHED?
|
||||
/* We are at the end of the final buffer, should we check for
|
||||
XML_SUSPENDED, XML_FINISHED?
|
||||
*/
|
||||
if (startTagLevel == 0)
|
||||
return XML_ERROR_NO_ELEMENTS;
|
||||
@@ -2537,8 +2535,8 @@ doContent(XML_Parser parser,
|
||||
}
|
||||
else if (defaultHandler)
|
||||
reportDefault(parser, enc, s, end);
|
||||
/* We are at the end of the final buffer, should we check for
|
||||
XML_SUSPENDED, XML_FINISHED?
|
||||
/* We are at the end of the final buffer, should we check for
|
||||
XML_SUSPENDED, XML_FINISHED?
|
||||
*/
|
||||
if (startTagLevel == 0) {
|
||||
*eventPP = end;
|
||||
@@ -2550,7 +2548,7 @@ doContent(XML_Parser parser,
|
||||
}
|
||||
*nextPtr = end;
|
||||
return XML_ERROR_NONE;
|
||||
case XML_TOK_DATA_CHARS:
|
||||
case XML_TOK_DATA_CHARS:
|
||||
{
|
||||
XML_CharacterDataHandler charDataHandler = characterDataHandler;
|
||||
if (charDataHandler) {
|
||||
@@ -2590,7 +2588,7 @@ doContent(XML_Parser parser,
|
||||
}
|
||||
*eventPP = s = next;
|
||||
switch (ps_parsing) {
|
||||
case XML_SUSPENDED:
|
||||
case XML_SUSPENDED:
|
||||
*nextPtr = next;
|
||||
return XML_ERROR_NONE;
|
||||
case XML_FINISHED:
|
||||
@@ -2949,27 +2947,27 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
|
||||
static const XML_Char xmlNamespace[] = {
|
||||
ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
|
||||
ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
|
||||
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
|
||||
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
|
||||
ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
|
||||
ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
|
||||
ASCII_e, '\0'
|
||||
};
|
||||
static const int xmlLen =
|
||||
static const int xmlLen =
|
||||
(int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
|
||||
static const XML_Char xmlnsNamespace[] = {
|
||||
ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
|
||||
ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
|
||||
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
|
||||
ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
|
||||
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
|
||||
ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
|
||||
ASCII_SLASH, '\0'
|
||||
};
|
||||
static const int xmlnsLen =
|
||||
static const int xmlnsLen =
|
||||
(int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
|
||||
|
||||
XML_Bool mustBeXML = XML_FALSE;
|
||||
XML_Bool isXML = XML_TRUE;
|
||||
XML_Bool isXMLNS = XML_TRUE;
|
||||
|
||||
|
||||
BINDING *b;
|
||||
int len;
|
||||
|
||||
@@ -2996,7 +2994,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
|
||||
if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
|
||||
isXML = XML_FALSE;
|
||||
|
||||
if (!mustBeXML && isXMLNS
|
||||
if (!mustBeXML && isXMLNS
|
||||
&& (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
|
||||
isXMLNS = XML_FALSE;
|
||||
}
|
||||
@@ -3207,7 +3205,7 @@ ignoreSectionProcessor(XML_Parser parser,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
|
||||
enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
|
||||
endPtr, (XML_Bool)!ps_finalBuffer);
|
||||
if (result != XML_ERROR_NONE)
|
||||
return result;
|
||||
@@ -3489,7 +3487,7 @@ entityValueInitProcessor(XML_Parser parser,
|
||||
const char *next = start;
|
||||
eventPtr = start;
|
||||
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
tok = XmlPrologTok(encoding, start, end, &next);
|
||||
eventEndPtr = next;
|
||||
if (tok <= 0) {
|
||||
@@ -3517,7 +3515,7 @@ entityValueInitProcessor(XML_Parser parser,
|
||||
if (result != XML_ERROR_NONE)
|
||||
return result;
|
||||
switch (ps_parsing) {
|
||||
case XML_SUSPENDED:
|
||||
case XML_SUSPENDED:
|
||||
*nextPtr = next;
|
||||
return XML_ERROR_NONE;
|
||||
case XML_FINISHED:
|
||||
@@ -3582,7 +3580,7 @@ externalParEntProcessor(XML_Parser parser,
|
||||
}
|
||||
|
||||
processor = prologProcessor;
|
||||
return doProlog(parser, encoding, s, end, tok, next,
|
||||
return doProlog(parser, encoding, s, end, tok, next,
|
||||
nextPtr, (XML_Bool)!ps_finalBuffer);
|
||||
}
|
||||
|
||||
@@ -3632,7 +3630,7 @@ prologProcessor(XML_Parser parser,
|
||||
{
|
||||
const char *next = s;
|
||||
int tok = XmlPrologTok(encoding, s, end, &next);
|
||||
return doProlog(parser, encoding, s, end, tok, next,
|
||||
return doProlog(parser, encoding, s, end, tok, next,
|
||||
nextPtr, (XML_Bool)!ps_finalBuffer);
|
||||
}
|
||||
|
||||
@@ -3649,7 +3647,7 @@ doProlog(XML_Parser parser,
|
||||
#ifdef XML_DTD
|
||||
static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
|
||||
#endif /* XML_DTD */
|
||||
static const XML_Char atypeCDATA[] =
|
||||
static const XML_Char atypeCDATA[] =
|
||||
{ ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
|
||||
static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
|
||||
static const XML_Char atypeIDREF[] =
|
||||
@@ -3670,7 +3668,7 @@ doProlog(XML_Parser parser,
|
||||
static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
|
||||
|
||||
/* save one level of indirection */
|
||||
DTD * const dtd = _dtd;
|
||||
DTD * const dtd = _dtd;
|
||||
|
||||
const char **eventPP;
|
||||
const char **eventEndPP;
|
||||
@@ -3703,6 +3701,9 @@ doProlog(XML_Parser parser,
|
||||
return XML_ERROR_UNCLOSED_TOKEN;
|
||||
case XML_TOK_PARTIAL_CHAR:
|
||||
return XML_ERROR_PARTIAL_CHAR;
|
||||
case -XML_TOK_PROLOG_S:
|
||||
tok = -tok;
|
||||
break;
|
||||
case XML_TOK_NONE:
|
||||
#ifdef XML_DTD
|
||||
/* for internal PE NOT referenced between declarations */
|
||||
@@ -3782,15 +3783,17 @@ doProlog(XML_Parser parser,
|
||||
#endif /* XML_DTD */
|
||||
dtd->hasParamEntityRefs = XML_TRUE;
|
||||
if (startDoctypeDeclHandler) {
|
||||
XML_Char *pubId;
|
||||
if (!XmlIsPublicId(enc, s, next, eventPP))
|
||||
return XML_ERROR_PUBLICID;
|
||||
doctypePubid = poolStoreString(&tempPool, enc,
|
||||
s + enc->minBytesPerChar,
|
||||
next - enc->minBytesPerChar);
|
||||
if (!doctypePubid)
|
||||
pubId = poolStoreString(&tempPool, enc,
|
||||
s + enc->minBytesPerChar,
|
||||
next - enc->minBytesPerChar);
|
||||
if (!pubId)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
normalizePublicId((XML_Char *)doctypePubid);
|
||||
normalizePublicId(pubId);
|
||||
poolFinish(&tempPool);
|
||||
doctypePubid = pubId;
|
||||
handleDefault = XML_FALSE;
|
||||
goto alreadyChecked;
|
||||
}
|
||||
@@ -3844,8 +3847,8 @@ doProlog(XML_Parser parser,
|
||||
entity->publicId))
|
||||
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
|
||||
if (dtd->paramEntityRead) {
|
||||
if (!dtd->standalone &&
|
||||
notStandaloneHandler &&
|
||||
if (!dtd->standalone &&
|
||||
notStandaloneHandler &&
|
||||
!notStandaloneHandler(handlerArg))
|
||||
return XML_ERROR_NOT_STANDALONE;
|
||||
}
|
||||
@@ -4283,7 +4286,7 @@ doProlog(XML_Parser parser,
|
||||
switch (tok) {
|
||||
case XML_TOK_PARAM_ENTITY_REF:
|
||||
/* PE references in internal subset are
|
||||
not allowed within declarations. */
|
||||
not allowed within declarations. */
|
||||
return XML_ERROR_PARAM_ENTITY_REF;
|
||||
case XML_TOK_XML_DECL:
|
||||
return XML_ERROR_MISPLACED_XML_PI;
|
||||
@@ -4404,7 +4407,7 @@ doProlog(XML_Parser parser,
|
||||
return XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
if (entity->textPtr) {
|
||||
enum XML_Error result;
|
||||
XML_Bool betweenDecl =
|
||||
XML_Bool betweenDecl =
|
||||
(role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
|
||||
result = processInternalEntity(parser, entity, betweenDecl);
|
||||
if (result != XML_ERROR_NONE)
|
||||
@@ -4599,7 +4602,7 @@ doProlog(XML_Parser parser,
|
||||
reportDefault(parser, enc, s, next);
|
||||
|
||||
switch (ps_parsing) {
|
||||
case XML_SUSPENDED:
|
||||
case XML_SUSPENDED:
|
||||
*nextPtr = next;
|
||||
return XML_ERROR_NONE;
|
||||
case XML_FINISHED:
|
||||
@@ -4669,7 +4672,7 @@ epilogProcessor(XML_Parser parser,
|
||||
}
|
||||
eventPtr = s = next;
|
||||
switch (ps_parsing) {
|
||||
case XML_SUSPENDED:
|
||||
case XML_SUSPENDED:
|
||||
*nextPtr = next;
|
||||
return XML_ERROR_NONE;
|
||||
case XML_FINISHED:
|
||||
@@ -4712,12 +4715,12 @@ processInternalEntity(XML_Parser parser, ENTITY *entity,
|
||||
#ifdef XML_DTD
|
||||
if (entity->is_param) {
|
||||
int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
|
||||
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
|
||||
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
|
||||
next, &next, XML_FALSE);
|
||||
}
|
||||
else
|
||||
else
|
||||
#endif /* XML_DTD */
|
||||
result = doContent(parser, tagLevel, internalEncoding, textStart,
|
||||
result = doContent(parser, tagLevel, internalEncoding, textStart,
|
||||
textEnd, &next, XML_FALSE);
|
||||
|
||||
if (result == XML_ERROR_NONE) {
|
||||
@@ -4757,13 +4760,13 @@ internalEntityProcessor(XML_Parser parser,
|
||||
#ifdef XML_DTD
|
||||
if (entity->is_param) {
|
||||
int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
|
||||
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
|
||||
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
|
||||
next, &next, XML_FALSE);
|
||||
}
|
||||
else
|
||||
#endif /* XML_DTD */
|
||||
result = doContent(parser, openEntity->startTagLevel, internalEncoding,
|
||||
textStart, textEnd, &next, XML_FALSE);
|
||||
result = doContent(parser, openEntity->startTagLevel, internalEncoding,
|
||||
textStart, textEnd, &next, XML_FALSE);
|
||||
|
||||
if (result != XML_ERROR_NONE)
|
||||
return result;
|
||||
@@ -4784,7 +4787,7 @@ internalEntityProcessor(XML_Parser parser,
|
||||
int tok;
|
||||
processor = prologProcessor;
|
||||
tok = XmlPrologTok(encoding, s, end, &next);
|
||||
return doProlog(parser, encoding, s, end, tok, next, nextPtr,
|
||||
return doProlog(parser, encoding, s, end, tok, next, nextPtr,
|
||||
(XML_Bool)!ps_finalBuffer);
|
||||
}
|
||||
else
|
||||
@@ -4793,8 +4796,8 @@ internalEntityProcessor(XML_Parser parser,
|
||||
processor = contentProcessor;
|
||||
/* see externalEntityContentProcessor vs contentProcessor */
|
||||
return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
|
||||
nextPtr, (XML_Bool)!ps_finalBuffer);
|
||||
}
|
||||
nextPtr, (XML_Bool)!ps_finalBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
static enum XML_Error PTRCALL
|
||||
@@ -4947,7 +4950,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
|
||||
if (!entity->textPtr) {
|
||||
if (enc == encoding)
|
||||
eventPtr = ptr;
|
||||
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
|
||||
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
|
||||
}
|
||||
else {
|
||||
enum XML_Error result;
|
||||
|
||||
Reference in New Issue
Block a user