[Aptitude-svn-commit] r3581 - in branches/aptitude-0.3/aptitude: . src/vscreen

Daniel Burrows dburrows@costa.debian.org
Sun Jul 3 16:54:59 UTC 2005


Author: dburrows
Date: Sun Jul  3 16:54:57 2005
New Revision: 3581

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/vscreen/transcode.cc
Log:
Be more robust against coding errors: try to decode the rest of the string.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Sun Jul  3 16:54:57 2005
@@ -1,5 +1,11 @@
 2005-07-03  Daniel Burrows  <dburrows@debian.org>
 
+	* src/vscreen/transcode.cc:
+
+	  When coding errors are encountered, replace the offending
+	  characters with '?' and continue attempting to decode the rest
+	  of the string.
+
 	* src/vscreen/vs_pager.cc, src/vscreen/vs_pager.h:
 
 	  Use wide characters in the vs_pager, and transcode the input

Modified: branches/aptitude-0.3/aptitude/src/vscreen/transcode.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/transcode.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/transcode.cc	Sun Jul  3 16:54:57 2005
@@ -53,22 +53,34 @@
  *  isn't large enough, it will be repeatedly doubled.
  *
  *  \param state the iconv state to be used
+ *
  *  \param outbuf the buffer to which the string should be decoded.
  *         If \b null, a new buffer will be allocated.
+ *
  *  \param outbufsize the initial size of "outbuf", updated if
  *      outbuf is increased.  If this value is 0, an arbitrary small
  *      starting value will be used.
+ *
  *  \param inbuf the string to be decoded.
+ *
  *  \param inbufsize the size of inbuf.
+ *
  *  \param decoded location to write the number of bytes in the decoded string.
+ *
+ *  \param errf a callback to handle encoding errors: it is passed the
+ *  current decoding state, and returns 'true' to continue and 'false'
+ *  to abort (after possibly adjusting said state).
  */
 static bool transcode_buffer(iconv_t &state,
 			     char *&outbuf,
 			     size_t &outbufsize,
 			     const char *inbuf,
 			     size_t inbufsize,
-			     size_t &decoded)
+			     size_t &decoded,
+			     const char *outencoding)
 {
+  bool rval=true;
+
   if(outbufsize == 0 || outbuf == NULL)
     {
       free(outbuf);
@@ -112,8 +124,81 @@
 
 	  if(errno != E2BIG)
 	    {
-	      decoded=outbufsize-outremaining;
-	      return false;
+	      rval=false;
+	      // Reset the output to initial state.
+	      size_t result = iconv(state, NULL, NULL, &outbufcur, &outremaining);
+
+	      while(result == (size_t)(-1))
+		{
+		  assert(errno == E2BIG);
+
+		  size_t idx = outbufcur-outbuf;
+		  outremaining += outbufsize;
+		  outbufsize *= 2;
+		  outbuf = (char *) realloc(outbuf,outbufsize);
+		  outbufcur = outbuf+idx;
+
+		  result = iconv(state, NULL, NULL, &outbufcur, &outremaining);
+		}
+
+	      // Open a *new* iconv to spit a '?' onto the decoded
+	      // output.
+	      iconv_t state2 = iconv_open(outencoding, "ASCII");
+
+	      if(state2 == (iconv_t)(-1))
+		{
+		  decoded = outbufsize-outremaining;
+		  return false;
+		}
+
+	      const char *errbuf = "?";
+	      size_t errbufsize = strlen(errbuf);
+
+	      result = iconv(state2, const_cast<char **>(&errbuf),
+			     &errbufsize, &outbufcur, &outremaining);
+
+
+	      while(result == (size_t)(-1))
+		{
+		  if(errno != E2BIG)
+		    {
+		      decoded = outbufsize-outremaining;
+		      iconv_close(state2);
+		      return false;
+		    }
+
+		  size_t idx = outbufcur-outbuf;
+		  outremaining += outbufsize;
+		  outbufsize *= 2;
+		  outbuf = (char *) realloc(outbuf, outbufsize);
+		  outbufcur = outbuf+idx;
+
+		  result = iconv(state2, const_cast<char **>(&errbuf),
+				 &errbufsize, &outbufcur, &outremaining);
+		}
+
+	      assert(errbufsize == 0);
+
+	      // Return again to initial shift state
+	      result = iconv(state2, NULL, NULL, &outbufcur, &outremaining);
+	      while(result == (size_t)(-1))
+		{
+		  assert(errno == E2BIG);
+
+		  size_t idx = outbufcur-outbuf;
+		  outremaining += outbufsize;
+		  outbufsize *= 2;
+		  outbuf = (char *) realloc(outbuf, outbufsize);
+		  outbufcur = outbuf+idx;
+
+		  result = iconv(state2, NULL, NULL, &outbufcur, &outremaining);
+		}
+
+	      iconv_close(state2);
+
+	      // Ok, skip the bad input character.
+	      ++inbuf;
+	      --inremaining;
 	    }
 	  else
 	    {
@@ -133,7 +218,7 @@
 
   decoded=outbufsize-outremaining;
 
-  return true;
+  return rval;
 }
 
 bool transcode(const char *s,
@@ -153,7 +238,7 @@
   size_t result_size = 0;
 
   bool rval = transcode_buffer(converter, outbuf, outbufsize,
-			       s, strlen(s), result_size);
+			       s, strlen(s), result_size, "WCHAR_T");
 
   if(outbuf != NULL)
     {
@@ -220,7 +305,7 @@
   bool rval = transcode_buffer(converter, outbuf, outbufsize,
 			       (char *) s,
 			       wcslen(s)*sizeof(wchar_t),
-			       result_size);
+			       result_size, encoding);
 
   if(outbuf != NULL)
     {




More information about the Aptitude-svn-commit mailing list