prisonerjohn / processing-web

0 stars 0 forks source link

[CLOSED] KeyboardFunctions example - array out of bounds on "[" key #123

Open prisonerjohn opened 10 years ago

prisonerjohn commented 10 years ago

Issue by twilsonb Thursday May 09, 2013 at 14:11 GMT Originally opened as https://github.com/processing/processing-web/issues/123


Error Description

The KeyboardFunctions example in Processing 2.0b8 on Mac OS X 10.8.3 accesses non-existent array indexes when keyboard characters between 'Z' and 'a' (exclusive) are pressed. This throws an exception in Java, but is treated as if the index was 0 in Processing.js.

The exception in Java when '[' is pressed is:

Exception in thread "Animation Thread" java.lang.ArrayIndexOutOfBoundsException: -6
    at KeyboardFunctions.keyPressed(KeyboardFunctions.java:83)
    at processing.core.PApplet.keyPressed(PApplet.java:3339)
    at processing.core.PApplet.handleKeyEvent(PApplet.java:3157)
    at processing.core.PApplet.dequeueEvents(PApplet.java:2606)
    at processing.core.PApplet.handleDraw(PApplet.java:2277)
    at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:243)
    at processing.core.PApplet.run(PApplet.java:2140)
    at java.lang.Thread.run(Thread.java:680)

Error Diagnosis

This exceptions occurs because the code assumes that 'Z' is next to 'a', and fails to account for the 6 character gap, which contains [ \ ] ^ _ `.

There are two alternate fixes to the keyPressed function:

The fix to keyPressed() is:

void keyPressed()
{

These two lines are modified from the original:

  // If the key is between 'A'(65) and 'Z' (90) or 'a' (97) and 'z' (122)
  if((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z')) {

This is the context of the code above (the function continues past this snippet):

    int keyIndex;
    if(key <= 'Z') {
      keyIndex = key-'A';
      letterHeight = maxHeight;
      fill(colors[key-'A']);
    } else {
      keyIndex = key-'a';
      letterHeight = minHeight;
      fill(colors[key-'a']);
    }
  } else {
    fill(0);
    letterHeight = 10;
  }
...

Edit: explain difference between impact of bug in Java and JavaScript.

prisonerjohn commented 10 years ago

Comment by twilsonb Thursday May 09, 2013 at 14:13 GMT


I can't seem to find a way to attach a file, and I'm very inexperienced with git (and this project). The entire fixed code file KeyboardFunctions.pde is:

/**
 * Keyboard Functions. 
 * Modified from code by Martin. 
 * Original 'Color Typewriter' concept by John Maeda. 
 * 
 * Click on the window to give it focus and press the letter keys to type colors. 
 * The keyboard function keyPressed() is called whenever
 * a key is pressed. keyReleased() is another keyboard
 * function that is called when a key is released.
 */

int maxHeight = 40;
int minHeight = 20;
int letterHeight = maxHeight; // Height of the letters
int letterWidth = 20;          // Width of the letter

int x = -letterWidth;          // X position of the letters
int y = 0;                      // Y position of the letters

boolean newletter;              

int numChars = 26;      // There are 26 characters in the alphabet
color[] colors = new color[numChars];

void setup()
{
  size(640, 360);
  noStroke();
  colorMode(HSB, numChars);
  background(numChars/2);
  // Set a gray value for each key
  for(int i = 0; i < numChars; i++) {
    colors[i] = color(i, numChars, numChars);    
  }
}

void draw()
{
  if(newletter == true) {
    // Draw the "letter"
    int y_pos;
    if (letterHeight == maxHeight) {
      y_pos = y;
      rect( x, y_pos, letterWidth, letterHeight );
    } else {
      y_pos = y + minHeight;
      rect( x, y_pos, letterWidth, letterHeight );
      fill(numChars/2);
      rect( x, y_pos-minHeight, letterWidth, letterHeight );
    }
    newletter = false;
  }
}

void keyPressed()
{
  // If the key is between 'A'(65) and 'Z' (90) or 'a' (97) and 'z' (122)
  if((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z')) {
    int keyIndex;
    if(key <= 'Z') {
      keyIndex = key-'A';
      letterHeight = maxHeight;
      fill(colors[key-'A']);
    } else {
      keyIndex = key-'a';
      letterHeight = minHeight;
      fill(colors[key-'a']);
    }
  } else {
    fill(0);
    letterHeight = 10;
  }

  newletter = true;

  // Update the "letter" position
  x = ( x + letterWidth ); 

  // Wrap horizontally
  if (x > width - letterWidth) {
    x = 0;
    y+= maxHeight;
  }

  // Wrap vertically
  if( y > height - letterHeight) {
    y = 0;      // reset y to 0
  }
}
prisonerjohn commented 10 years ago

Comment by aengelke Saturday May 18, 2013 at 11:03 GMT


It is working with Processing.js

prisonerjohn commented 10 years ago

Comment by twilsonb Saturday May 18, 2013 at 12:26 GMT


@aengelke the bug doesn't cause an exception in Processing.js because of the differences in array out of bounds handling in Java and JavaScript.

When '[' is pressed in Java, an exception is thrown for the index -6, but in JavaScript, the index is treated as if it were 0. I'll modify the original description to take this into account.

prisonerjohn commented 10 years ago

Comment by REAS Wednesday May 22, 2013 at 21:42 GMT


Fixed in the source. Thanks.