shithub: opusfile

Download patch

ref: cfa5956105a71501fc6aa1a583c118ba423975aa
parent: 116b703442e52a5dca635b5050d3d7165d2c9662
author: Timothy B. Terriberry <tterribe@xiph.org>
date: Mon Aug 12 05:48:32 EDT 2013

Minor UTF-8/UTF-16 cleanups.

- Reject 'not a character' values 0xFFFE and 0xFFFF.
- Remove some unnecessary string length checks.

--- a/examples/win32utf8.c
+++ b/examples/win32utf8.c
@@ -32,8 +32,9 @@
       dst[di++]=(char)(0x80|c0&0x3F);
       continue;
     }
-    else if(c0>=0xD800&&c0<0xDC00&&si+1<len){
+    else if(c0>=0xD800&&c0<0xDC00){
       unsigned c1;
+      /*This is safe, because c0 was not 0 and _src is NUL-terminated.*/
       c1=_src[si+1];
       if(c1>=0xDC00&&c1<0xE000){
         unsigned w;
@@ -48,9 +49,9 @@
         continue;
       }
     }
-    /*Anything else is either a valid 3-byte sequence, or an invalid
-       surrogate pair.
-      In the latter case, we just encode the value as a 3-byte
+    /*Anything else is either a valid 3-byte sequence, an invalid surrogate
+       pair, or 'not a character'.
+      In the latter two cases, we just encode the value as a 3-byte
        sequence anyway (producing technically invalid UTF-8).
       Later error handling will detect the problem, with a better
        chance of giving a useful error message.*/
--- a/src/stream.c
+++ b/src/stream.c
@@ -153,8 +153,9 @@
         dst[di++]=(wchar_t)c0;
         continue;
       }
-      else if(si+1<len){
+      else{
         int c1;
+        /*This is safe, because c0 was not 0 and _src is NUL-terminated.*/
         c1=(unsigned char)_src[si+1];
         if((c1&0xC0)==0x80){
           /*Found at least one continuation byte.*/
@@ -169,8 +170,9 @@
               continue;
             }
           }
-          else if(si+2<len){
+          else{
             int c2;
+            /*This is safe, because c1 was not 0 and _src is NUL-terminated.*/
             c2=(unsigned char)_src[si+2];
             if((c2&0xC0)==0x80){
               /*Found at least two continuation bytes.*/
@@ -178,16 +180,19 @@
                 wchar_t w;
                 /*Start byte says this is a 3-byte sequence.*/
                 w=(c0&0xF)<<12|(c1&0x3F)<<6|c2&0x3F;
-                if(w>=0x800U&&(w<0xD800||w>=0xE000)){
-                  /*This is a 3-byte sequence that is not overlong and not a
-                     UTF-16 surrogate pair value.*/
+                if(w>=0x800U&&(w<0xD800||w>=0xE000)&&w<0xFFFE){
+                  /*This is a 3-byte sequence that is not overlong, not a
+                     UTF-16 surrogate pair value, and not a 'not a character'
+                     value.*/
                   dst[di++]=w;
                   si+=2;
                   continue;
                 }
               }
-              else if(si+3<len){
+              else{
                 int c3;
+                /*This is safe, because c2 was not 0 and _src is
+                   NUL-terminated.*/
                 c3=(unsigned char)_src[si+3];
                 if((c3&0xC0)==0x80){
                   /*Found at least three continuation bytes.*/