Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xml fixes [EPF-11362] #28

Merged
merged 5 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
2024-04-29 Doug Simons <[email protected]>

* NSXMLNode.m:
Fix execute_xpath() to return an NSError when xpath expression can't
be evaluated instead of just calling NSLog.

* NSXMLElement.m:
Fix setAttributes: and setAttributesWithDictionary: to remove previous
attributes.
Partially fix setNamespaces: to set old ns to NULL, but usage in other
nodes in the tree are not cleaned up, may lead to a crash.

2020-12-23 Doug Simons <[email protected]>

* NSDateFormatter.m:
Expand Down
22 changes: 20 additions & 2 deletions Source/NSXMLElement.m
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,15 @@ - (void) setAttributes: (NSArray*)attributes
NSEnumerator *enumerator = [attributes objectEnumerator];
NSXMLNode *attribute;

// FIXME: Remove all previous attributes
// Remove all previous attributes
NSArray *currentAttributes = [self attributes];
for (int index = [currentAttributes count]-1; index >= 0; index--)
{
NSXMLNode *attrNode = [currentAttributes objectAtIndex:index];
NSString *name = [attrNode name];
[self removeAttributeForName:name];
}

while ((attribute = [enumerator nextObject]) != nil)
{
[self addAttribute: attribute];
Expand All @@ -384,7 +392,15 @@ - (void) setAttributesWithDictionary: (NSDictionary*)attributes
NSEnumerator *en = [attributes keyEnumerator];
NSString *key;

// FIXME: Remove all previous attributes
// Remove all previous attributes
NSArray *currentAttributes = [self attributes];
for (int index = [currentAttributes count]-1; index >= 0; index--)
{
NSXMLNode *attrNode = [currentAttributes objectAtIndex:index];
NSString *name = [attrNode name];
[self removeAttributeForName:name];
}

while ((key = [en nextObject]) != nil)
{
NSString *val = [[attributes objectForKey: key] stringValue];
Expand Down Expand Up @@ -565,6 +581,8 @@ - (void) setNamespaces: (NSArray*)namespaces

// Remove old namespaces
xmlFreeNsList(internal->node->nsDef);
if (internal->node->ns == internal->node->nsDef)
internal->node->ns = NULL;
internal->node->nsDef = NULL;

// Add new ones
Expand Down
11 changes: 10 additions & 1 deletion Source/NSXMLNode.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define GS_XMLNODETYPE xmlNode

#import "Foundation/NSCharacterSet.h"
#import "Foundation/NSError.h"
#import "NSXMLPrivate.h"
#import "GSInternal.h"
GS_PRIVATE_INTERNAL(NSXMLNode)
Expand Down Expand Up @@ -831,7 +832,15 @@ - (void) _invalidate
xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
if (xpathObj == NULL)
{
NSLog(@"Error: unable to evaluate xpath expression \"%s\"", xpathExpr);
NSLog(@"Error: unable to evaluate xpath expression \"%s\"", xpathExpr);
if (error != 0)
{
xmlError xmlError = xpathCtx->lastError;
NSString *message = [NSString stringWithFormat:@"Error: unable to evaluate xpath expression \"%s\" (%d)", xpathExpr, xmlError.code];
*error = [NSError errorWithDomain: @"LibXMLErrorDomain"
code: xmlError.code
userInfo: @{NSLocalizedDescriptionKey:message}];
}
xmlXPathFreeContext(xpathCtx);
return nil;
}
Expand Down
9 changes: 9 additions & 0 deletions Tests/base/NSXMLElement/attributes.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ int main()
NSInternalInconsistencyException,
"cannot add attributes to multiple parents");

[root1 setAttributes:@[attr2]];
PASS_EQUAL([root1 attributeForName: @"attr2"], attr2,
"setAttributes: added the new attribute");
PASS_EQUAL([root1 attributeForName: @"attr1"], nil,
"setAttributes: removed the old attribute");
PASS_EQUAL([root1 attributes], @[attr2], "attributes are just as set");
[root1 setAttributes:@[]];
PASS_EQUAL([root1 attributes], @[], "setAttributes:@[] removes all attributes");



[root1 release];
Expand Down
36 changes: 36 additions & 0 deletions Tests/base/NSXMLNode/xpath.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#import "ObjectTesting.h"
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSXMLElement.h>
#import <Foundation/NSXMLDocument.h>
#import <Foundation/NSXMLNode.h>
#import <Foundation/NSError.h>

int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];

NSString *sourceXML = @"<parent>"
"<chyld>buzz</chyld>"
"<otherchyld>woody</otherchyld>"
"<zorgtree>gollyfoo</zorgtree>"
"<ln:loner xmlns:ln=\"http://loner.ns\">POW</ln:loner>"
"</parent>";
NSXMLDocument *doc = [[[NSXMLDocument alloc] initWithXMLString:sourceXML options:0 error:NULL] autorelease];
PASS(doc != nil, "created a document from an XML string");

NSError *anError = nil;
NSXMLNode *node = [[doc nodesForXPath:@"//chyld" error:&anError] lastObject];
PASS(node != nil, "access chyld node");
PASS(anError == nil, "no error accessing chyld node");
PASS_EQUAL([node stringValue], @"buzz", "retrieve chyld node");

node = [[doc nodesForXPath:@"//ln:loner" error:&anError] lastObject];
PASS(node == nil, "can't access ln:loner node if namespace not defined at top");
PASS(anError != nil, "should get error when fail to access node");

[arp release];
arp = nil;

return 0;
}
// "<parent><chyld>buzz</chyld><otherchyld>woody</otherchyld><zorgtree>gollyfoo</zorgtree><ln:loner xmlns:ln=\"http://loner.ns\"></ln:loner></parent>"