diff --git a/src/attrs.c b/src/attrs.c index 20ebeac..e1c0956 100644 --- a/src/attrs.c +++ b/src/attrs.c @@ -900,28 +900,37 @@ static void FreeAnchor(TidyDocImpl* doc, Anchor *a) TidyDocFree( doc, a ); } +static uint anchorNameHash(ctmbstr s) +{ + uint hashval; + + for (hashval = 0; *s != '\0'; s++) { + tmbchar c = TY_(ToLower)( *s ); + hashval = c + 31*hashval; + } + + return hashval % ANCHOR_HASH_SIZE; +} + /* removes anchor for specific node */ -void TY_(RemoveAnchorByNode)( TidyDocImpl* doc, Node *node ) +void TY_(RemoveAnchorByNode)( TidyDocImpl* doc, ctmbstr name, Node *node ) { TidyAttribImpl* attribs = &doc->attribs; - Anchor *delme = NULL, *curr, *prev; - uint h; + Anchor *delme = NULL, *curr, *prev = NULL; + uint h = anchorNameHash(name); - for (h = 0; h < ANCHOR_HASH_SIZE; h++) { - prev = NULL; - for ( curr=attribs->anchor_hash[h]; curr!=NULL; curr=curr->next ) + for ( curr=attribs->anchor_hash[h]; curr!=NULL; curr=curr->next ) + { + if ( curr->node == node ) { - if ( curr->node == node ) - { - if ( prev ) - prev->next = curr->next; - else - attribs->anchor_hash[h] = curr->next; - delme = curr; - break; - } - prev = curr; + if ( prev ) + prev->next = curr->next; + else + attribs->anchor_hash[h] = curr->next; + delme = curr; + break; } + prev = curr; } FreeAnchor( doc, delme ); } @@ -939,25 +948,12 @@ static Anchor* NewAnchor( TidyDocImpl* doc, ctmbstr name, Node* node ) return a; } -static uint anchorNameHash(ctmbstr s) -{ - uint hashval; - - for (hashval = 0; *s != '\0'; s++) - hashval = *s + 31*hashval; - - return hashval % ANCHOR_HASH_SIZE; -} - /* add new anchor to namespace */ static Anchor* AddAnchor( TidyDocImpl* doc, ctmbstr name, Node *node ) { - uint h; TidyAttribImpl* attribs = &doc->attribs; Anchor *a = NewAnchor( doc, name, node ); - tmbstr lname = TY_(tmbstrdup)(doc->allocator, name); - lname = TY_(tmbstrtolower)(lname); - h = anchorNameHash(lname); + uint h = anchorNameHash(name); if ( attribs->anchor_hash[h] == NULL) attribs->anchor_hash[h] = a; @@ -969,19 +965,17 @@ static Anchor* AddAnchor( TidyDocImpl* doc, ctmbstr name, Node *node ) here->next = a; } - TidyDocFree(doc, lname); return attribs->anchor_hash[h]; } /* return node associated with anchor */ static Node* GetNodeByAnchor( TidyDocImpl* doc, ctmbstr name ) { - uint h; TidyAttribImpl* attribs = &doc->attribs; Anchor *found; + uint h = anchorNameHash(name); tmbstr lname = TY_(tmbstrdup)(doc->allocator, name); lname = TY_(tmbstrtolower)(lname); - h = anchorNameHash(lname); for ( found = attribs->anchor_hash[h]; found != NULL; found = found->next ) { diff --git a/src/attrs.h b/src/attrs.h index 0410695..1edec87 100644 --- a/src/attrs.h +++ b/src/attrs.h @@ -122,7 +122,7 @@ Bool TY_(IsValidHTMLID)(ctmbstr id); Bool TY_(IsValidXMLID)(ctmbstr id); /* removes anchor for specific node */ -void TY_(RemoveAnchorByNode)( TidyDocImpl* doc, Node *node ); +void TY_(RemoveAnchorByNode)( TidyDocImpl* doc, ctmbstr name, Node *node ); /* free all anchors */ void TY_(FreeAnchors)( TidyDocImpl* doc ); diff --git a/src/clean.c b/src/clean.c index 7a14a0f..0602ce8 100644 --- a/src/clean.c +++ b/src/clean.c @@ -2638,17 +2638,19 @@ void TY_(FixAnchors)(TidyDocImpl* doc, Node *node, Bool wantName, Bool wantId) if (id && !wantId /* make sure that Name has been emitted if requested */ - && (hadName || !wantName || NameEmitted) ) + && (hadName || !wantName || NameEmitted) ) { + if (!wantId && !wantName) + TY_(RemoveAnchorByNode)(doc, id->value, node); TY_(RemoveAttribute)(doc, node, id); + } if (name && !wantName /* make sure that Id has been emitted if requested */ - && (hadId || !wantId || IdEmitted) ) + && (hadId || !wantId || IdEmitted) ) { + if (!wantId && !wantName) + TY_(RemoveAnchorByNode)(doc, name->value, node); TY_(RemoveAttribute)(doc, node, name); - - if (TY_(AttrGetById)(node, TidyAttr_NAME) == NULL && - TY_(AttrGetById)(node, TidyAttr_ID) == NULL) - TY_(RemoveAnchorByNode)(doc, node); + } } if (node->content) diff --git a/src/lexer.c b/src/lexer.c index 708c393..9e5ed1e 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -1077,7 +1077,7 @@ void TY_(FreeAttrs)( TidyDocImpl* doc, Node *node ) if ( (attrIsID(av) || attrIsNAME(av)) && TY_(IsAnchorElement)(doc, node) ) { - TY_(RemoveAnchorByNode)( doc, node ); + TY_(RemoveAnchorByNode)( doc, av->value, node ); } }