Archives for: June 2017, 16

16/06/17

Permalink 09:38:52 am, Categories: Technology, Rant, 431 words   English (UK)

Bug in BizTalk LogicalAnd functoid

While unit testing my own functoids, I came across an odd scenario where my map was working with inline C#, but if I switched to testing the external assembly version, the results were completely different. Obviously I started with the assumption that my functoid was broken, but in fact it appears that it's Microsoft's LogicalAnd functoid which is broken, and has been since BizTalk 2006.

I must stress, that the failure only occurs when you are using the external assembly version of the functoid, which would occur only when you have set the script type preference on your map to give higher priority to the external assembly script type than the inline C# script type. And frankly I still don't know why you would ever want to do that. But if you do, the LogicalAnd functoid is broken.

In BizTalk 2004, the functoid used this code which works:


// Microsoft.BizTalk.BaseFunctoids.FunctoidScripts
public bool LogicalAnd(string val1, string val2)
{
	bool flag = false;
	try
	{
		flag = bool.Parse(val1);
	}
	catch (Exception)
	{
		if (BaseFunctoid.IsNumeric(val1))
		{
			int num = Convert.ToInt32(val1, CultureInfo.get_InvariantCulture());
			flag = (0 < num);
		}
		else
		{
			flag = false;
		}
	}
	if (flag)
	{
		try
		{
			bool flag2 = bool.Parse(val2);
			flag = (flag && flag2);
		}
		catch (Exception)
		{
			if (BaseFunctoid.IsNumeric(val2))
			{
				int num2 = Convert.ToInt32(val2, CultureInfo.get_InvariantCulture());
				bool flag3 = true;
				if (0 >= num2)
				{
					flag3 = false;
				}
				flag = (flag && flag3);
			}
			else
			{
				flag = false;
			}
		}
	}
	return flag;
}

but at some point, either in BizTalk 2006 or in 2006r2 they changed to this code:

// Microsoft.BizTalk.BaseFunctoids.FunctoidScripts
public bool LogicalAnd(string val1, string val2)
{
	bool flag = false;
	if (!bool.TryParse(val1, out flag))
	{
		if (BaseFunctoid.IsNumeric(val1))
		{
			int num = Convert.ToInt32(val1, CultureInfo.InvariantCulture);
			flag = (0 < num);
		}
		else
		{
			flag = false;
		}
	}
	if (flag)
	{
		bool flag2 = false;
		if (!bool.TryParse(val2, out flag2))
		{
			flag = (flag && flag2);
		}
		else if (BaseFunctoid.IsNumeric(val2))
		{
			int num2 = Convert.ToInt32(val2, CultureInfo.InvariantCulture);
			flag2 = true;
			if (0 >= num2)
			{
				flag2 = false;
			}
			flag = (flag && flag2);
		}
		else
		{
			flag = false;
		}
	}
	return flag;
}

The new code is cleaner, and uses the TryParse method of the Boolean, presumably to avoid the overhead of the try..catch block. But the sense of the second parse test is the wrong way round; that second exclamation mark shouldn't be there; and as a result this function will almost always return false.

The fact that this bug appears to have survived for a decade suggests that no-one ever chooses to prioritise external assemblies in their maps, but you never know.

A Boolean and function should be the easiest thing to get right, and it certainly shouldn't be difficult to have unit testing this function.

Blog Aggregate

This blog is actually a very special blog! It automatically aggregates all posts from all other blogs. This allows you to easily track everything that is posted on this system.

June 2017
Mon Tue Wed Thu Fri Sat Sun
<<  <   >  >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    

Search

Categories

Blog Aggregate

carbon14 News

carbon14 Blog

carbon14 Links

Information

Art

Projects

DTG Firmware Broadcasts

Meniscus Blog

Webcomic of the Week

My reading list


Linkblog

Friends

Service Providers

Comics

Misc

Syndicate this blog XML

What is RSS?

powered by
b2evolution