Monday, January 28, 2008

Using REFCURSOR Bind Variables In Oracle SQL/Plus

I came across this tip here. Here is the output I tried on my machine. Another tutorial is also available in SQL/Plus User Guide.

SQL>
SQL> column owner Format a10;
SQL> column object_id Format 9999;
SQL> column object_type Format a10;
SQL>
SQL> CREATE OR REPLACE PROCEDURE sp_qry_all_object(cur_ds IN OUT SYS_REFCURSOR) AS
2 BEGIN
3 OPEN cur_ds FOR select owner, object_id, object_type from all_objects where object_id<500 and owner='PUBLIC';
4 END;
5 /

Procedure created.

SQL>
SQL> variable cur1 REFCURSOR;
SQL> exec sp_qry_all_object(:cur1);

PL/SQL procedure successfully completed.

SQL> print cur1;

OWNER OBJECT_ID OBJECT_TYP
---------- --------- ----------
PUBLIC 223 SYNONYM
PUBLIC 278 SYNONYM
PUBLIC 272 SYNONYM
PUBLIC 275 SYNONYM

SQL>
SQL> CREATE OR REPLACE FUNCTION sf_qry_all_object RETURN SYS_REFCURSOR
2 AS
3 cur_ds SYS_REFCURSOR;
4 BEGIN
5 OPEN cur_ds FOR select owner, object_id, object_type from all_objects where object_id<500 and owner='PUBLIC';
6 RETURN (cur_ds);
7 END;
8 /

Function created.

SQL>
SQL> variable cur2 REFCURSOR;
SQL> exec :cur2 := sf_qry_all_object;

PL/SQL procedure successfully completed.

SQL> print cur2;

OWNER OBJECT_ID OBJECT_TYP
---------- --------- ----------
PUBLIC 223 SYNONYM
PUBLIC 278 SYNONYM
PUBLIC 272 SYNONYM
PUBLIC 275 SYNONYM

Tips For Boosting .NET WinForm Performance

In this MSDN article, tips were suggested for boosting .NET WinForm Performance and I summarized as follows.
  1. Load fewer modules at startup
  2. Precompile assemblies using NGen
  3. Place strong-named assemblies in the GAC
  4. Avoid base address collisions
    • dumpbin can check the preferred base address of Dlls.
  5. Avoid blocking on the UI thread
  6. Perform lazy processing
    • Some operations can be implemented in the Idle event and will be processed when applications are idle.
  7. Populate controls more quickly
    • The following code snippet shows how to avoid constant repainting.
      listView1.BeginUpdate();
      for(int i = 0; i < 10000; i++)
      {
      ListViewItem listItem = new ListViewItem("Item"+i.ToString() );
      listView1.Items.Add(listItem);
      }
      listView1.EndUpdate();
  8. Exercise more control over data binding
    • BindingSource can help improve performance.
      this.bindingSource1.SuspendBinding();
      for (int i = 0; i < 1000; i++)
      {
      tbl.Rows[0][0] = "suspend row " + i.ToString();
      }
      this.bindingSource1.ResumeBinding();
  9. Reduce repainting
    • Use SuspendLayout method whenever possible to minimize the number of Layout events.
    • Call Invalidate method and pass the area that needs to be repainted as an argument to Invalidate.
  10. Use double buffering
  11. Manage memory usage
    • If controls are added and removed from WinForm dynamically, call Dispose on them. Otherwise, extra unwanted handles would be accumulated in the process.
  12. Use reflection wisely

Thursday, January 24, 2008

Links for 2008-01-24

  • Beautiful Code
    • Chapter 26 - Labor-Saving Architecture: An Object-Oriented Framework for Networked Software :
      • The commonality was achieved by adopting Template Method pattern. That is, common steps in a logging server were defined in the Logging_server base class's run() method, deferring specialization of individual steps of its operation to hook methods in derived classes.
      • The variability was achieved by adopting Wrapper Facade pattern. That is, the variability of semantic and syntactic differences, such as synchronization and IPC mechanisms, was hidden into base classes, such as Acceptor and Mutex . Then using C++ template feature, Logging_server could choose the appropriate Acceptor and Mutex subclasses in a parameterized way.

Saturday, January 5, 2008

ManagedSpy - A Testing Tool For Managed WinForm Applications

ManagedSpy is a tool for access the properties and events of managed windows applications at run time. It's good for debugging or testing Windows Forms controls and is equivalent to Spy++ for unmanaged windows applications.

ManagedSpy is acutally an example demonstrating the usage of ManagedSpyLib. ManagedSpyLib introduced a class, ControlProxy, with which we can get or set properties or subscribe to events of a System.Windows.Forms.Control in another process.

An introduction to ManagedSpy and the internal of ManagedSpyLib can be found in this MSDN article. The following is a testing program listed in the article for testing a WinForm application which has 2 textboxes accepting 2 integers and one button which multiply the 2 integers and shows the product in a third textobx. The lines of code in the blue color use the methods of ControlProxy. As you can see, the testing program programmatically accesses the three textbox controls and one button control in another WinForm program.
private void button1_Click(object sender, EventArgs e)
{
Process[] procs = Process.GetProcessesByName("Multiply");
if (procs.Length != 1) return;
ControlProxy proxy =
ControlProxy.FromHandle(procs[0].MainWindowHandle);
if (proxy == null) return;

//find the controls we are interested in...
if (cbutton1 == null)
{
foreach (ControlProxy child in proxy.Children)
{
if (child.GetComponentName() == "textBox1") {
textBox1 = child;
}
else if (child.GetComponentName() == "textBox2") {
textBox2 = child;
}
else if (child.GetComponentName() == "textBox3") {
textBox3 = child;
}
else if (child.GetComponentName() == "button1") {
cbutton1 = child;
}
}

//sync testchanged on textbox3 so we can tell if it has changed.
textBox1.SetValue("Text", "5");
textBox2.SetValue("Text", "7");
textBox3.SetValue("Text", "");
textBox3.EventFired +=
new ControlProxyEventHandler(textBox3_EventFired);
textBox3.SubscribeEvent("TextChanged");
}
else textBox3.SetValue("Text", "");

//now click on the button to start the test...
if (cbutton1 != null)
{
cbutton1.SendMessage(WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
cbutton1.SendMessage(WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
Application.DoEvents();
}

if (result == 35) MessageBox.Show("Passed!");
else MessageBox.Show("Fail!");
}

void textBox3_EventFired(object sender, ProxyEventArgs ed)
{
int val;
if (int.TryParse((string)textBox3.GetValue("Text"), out val)
{
result = val;
}
}

Review Code for Security Defects

In a limited time constraint, what should we look for when reviewing code for security bugs? In this MSDN article, the author suggested to check for the following bugs in code review.

Buffer Overruns in C/C++
void function(char *p) {
char buff[16];
...
strcpy(buff,p);
...
}
When see code like this, trace the variable p back to its source. If it came from an untrusted input, or is not checked for validity close to the point at which it's copied, then it's a security bug.
while (*s != '\\')
*d++ = *s++;
The loop will stop when pointer s hits '\', but pointer d is not checked. The buffer to which pointer d points may be overrun.

Integer Overflows in C/C++
void function(char *b1, size_t c1, char *b2, size_t c2) {
const size_t MAX = 48;
if (c1+c2 > MAX) return;
char *pBuff = new char[MAX];
memcpy(pBuff, b1, c1);
memcpy(pBuff+c1, b2, c2);
}
We may have an integer overflow bug, when the sum of c1 and c2 could exceed the maximum of an integer, i.e., 2^32-1. A rule of thumb is suggested: if you perform a mathematical operation in an expression that is used in a comparison, then you have a potential to overflow and underflow data.

Data Access Code
Don't hard code passwords in connection strings or connect to database using administrative accounts. Also, A database query using string concatenation is a potential security defect and should be fixed by using parameterized queries.

Web Page Code
Hello, <% Response.Write(Request.QueryString("Name")) %>
For code like this, be aware of cross-site scripting issues.

Secrets and Cryptography
Don't store secret data in code, such as passwords and cryptographic keys. Don't create one's own magic cryptographic algorithms, like using an embedded key to XOR a data stream.