فهرست منبع

修改死循环

loubw 1 هفته پیش
والد
کامیت
99246882a5
2فایلهای تغییر یافته به همراه97 افزوده شده و 76 حذف شده
  1. 65 49
      fpdf.go
  2. 32 27
      splittext.go

+ 65 - 49
fpdf.go

@@ -2658,14 +2658,19 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
 			}
 		}
 	}
-	sep := -1
+	//sep := -1
 	i := 0
 	j := 0
 	l := 0
-	ls := 0
-	ns := 0
+	//ls := 0
+	//ns := 0
 	nl := 1
+	lines := []string{}
 	for i < nb {
+		// 这里是为了防止内存溢出,曾出现过前面是汉字后面是非汉字,lines为["汉字汉字汉字","","","".....]无限个""导致内存溢出
+		if len(lines) > len(srune) {
+			break
+		}
 		// Get next character
 		var c rune
 		if f.isCurrentUTF8 {
@@ -2694,21 +2699,22 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
 				f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
 			}
 			i++
-			sep = -1
+			lines = append(lines, s[j:i])
+			//sep = -1
 			j = i
 			l = 0
-			ns = 0
+			//ns = 0
 			nl++
 			if len(borderStr) > 0 && nl == 2 {
 				b = b2
 			}
 			continue
 		}
-		if c == ' ' || isChinese(c) {
-			sep = i
-			ls = l
-			ns++
-		}
+		//if c == ' ' || isChinese(c) {
+		//	sep = i
+		//	ls = l
+		//	ns++
+		//}
 		if int(c) >= len(cw) {
 			f.err = fmt.Errorf("character outside the supported range: %s", string(c))
 			return
@@ -2719,49 +2725,59 @@ func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill
 			l += cw[int(c)]
 		}
 		if l > wmax {
+			///////////////
+			// 如果第一个字就超宽了,别循环了,会死循环
+			if i == 0 {
+				break
+			}
 			// Automatic line break
-			if sep == -1 {
-				if i == j {
-					i++
-				}
-				if f.ws > 0 {
-					f.ws = 0
-					f.out("0 Tw")
-				}
-				if f.isCurrentUTF8 {
-					f.CellFormat(w, h, string(srune[j:i]), b, 2, alignStr, fill, 0, "")
-				} else {
-					f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
-				}
+			//if sep == -1 {
+			//	if i == j {
+			//		i++
+			//	}
+			//	if f.ws > 0 {
+			//		f.ws = 0
+			//		f.out("0 Tw")
+			//	}
+			//	if f.isCurrentUTF8 {
+			//		f.CellFormat(w, h, string(srune[j:i]), b, 2, alignStr, fill, 0, "")
+			//	} else {
+			//		f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
+			//	}
+			//} else {
+			//	if alignStr == "J" {
+			//		if ns > 1 {
+			//			f.ws = float64((wmax-ls)/1000) * f.fontSize / float64(ns-1)
+			//		} else {
+			//			f.ws = 0
+			//		}
+			//		f.outf("%.3f Tw", f.ws*f.k)
+			//	}
+			//	if f.isCurrentUTF8 {
+			//		f.CellFormat(w, h, string(srune[j:sep]), b, 2, alignStr, fill, 0, "")
+			//	} else {
+			//		f.CellFormat(w, h, s[j:sep], b, 2, alignStr, fill, 0, "")
+			//	}
+			//	//////////
+			//	// i = sep + 1
+			//	/////////
+			//	i = sep
+			//}
+			i++
+			lines = append(lines, s[j:i])
+			if f.ws > 0 {
+				f.ws = 0
+				f.out("0 Tw")
+			}
+			if f.isCurrentUTF8 {
+				f.CellFormat(w, h, string(srune[j:i]), b, 2, alignStr, fill, 0, "")
 			} else {
-				///////////////
-				// 如果第一个字就超宽了,别循环了,会死循环
-				if i==0{
-					break
-				}
-
-				if alignStr == "J" {
-					if ns > 1 {
-						f.ws = float64((wmax-ls)/1000) * f.fontSize / float64(ns-1)
-					} else {
-						f.ws = 0
-					}
-					f.outf("%.3f Tw", f.ws*f.k)
-				}
-				if f.isCurrentUTF8 {
-					f.CellFormat(w, h, string(srune[j:sep]), b, 2, alignStr, fill, 0, "")
-				} else {
-					f.CellFormat(w, h, s[j:sep], b, 2, alignStr, fill, 0, "")
-				}
-				//////////
-				// i = sep + 1
-				/////////
-				i=sep
+				f.CellFormat(w, h, s[j:i], b, 2, alignStr, fill, 0, "")
 			}
-			sep = -1
+			//sep = -1
 			j = i
 			l = 0
-			ns = 0
+			//ns = 0
 			nl++
 			if len(borderStr) > 0 && nl == 2 {
 				b = b2
@@ -2934,7 +2950,7 @@ func (f *Fpdf) WriteLinkID(h float64, displayStr string, linkID int) {
 //
 // width indicates the width of the box the text will be drawn in. This is in
 // the unit of measure specified in New(). If it is set to 0, the bounding box
-//of the page will be taken (pageWidth - leftMargin - rightMargin).
+// of the page will be taken (pageWidth - leftMargin - rightMargin).
 //
 // lineHeight indicates the line height in the unit of measure specified in
 // New().

+ 32 - 27
splittext.go

@@ -2,8 +2,6 @@ package gofpdf
 
 import (
 	"math"
-	//	"strings"
-	"unicode"
 )
 
 // SplitText splits UTF-8 encoded text into several lines using the current
@@ -11,46 +9,53 @@ import (
 // function can be used to determine the total height of wrapped text for
 // vertical placement purposes.
 func (f *Fpdf) SplitText(txt string, w float64) (lines []string) {
-	cw := f.currentFont.Cw  // 字符宽度
+	cw := f.currentFont.Cw                                        // 字符宽度
 	wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize)) // 框的宽度
-	s := []rune(txt) // Return slice of UTF-8 runes
-	nb := len(s) // 字符长度
+	s := []rune(txt)                                              // Return slice of UTF-8 runes
+	nb := len(s)                                                  // 字符长度
 	// 去掉结尾的换行符
 	for nb > 0 && s[nb-1] == '\n' {
 		nb--
 	}
 	s = s[0:nb] //去掉结尾的换行符
-	sep := -1
+	//sep := -1
 	i := 0 // 遍历时的下标
 	j := 0 // 换行时保留的上一行结束的位置
 	l := 0 // 现在的长度
 	// 遍历字符串(去掉换行符之后的)
 	for i < nb {
-		c := s[i] // 当前字符
-		l += cw[c] // 当前需要的长度
-		if unicode.IsSpace(c) || isChinese(c) { // 判断是不是空格类字符和中文
-			sep = i
+
+		// 这里是为了防止内存溢出,曾出现过前面是汉字后面是非汉字,lines为["汉字汉字汉字","","","".....]无限个""导致内存溢出
+		if len(lines) > len(s) {
+			break
 		}
+
+		c := s[i]  // 当前字符
+		l += cw[c] // 当前需要的长度
+		//if unicode.IsSpace(c) || isChinese(c) { // 判断是不是空格类字符和中文
+		//	sep = i
+		//}
 		// 如果换行或者超长了
 		if c == '\n' || l > wmax {
-			if sep == -1 {
-				if i == j {
-					i++
-				}
-				sep = i
-			} else {
-				///////////////
-				// 如果第一个字就超宽了,别循环了,会死循环
-				if i==0{
-					break
-				}
-				///////////////
-				//i = sep + 1
-				//////////////
-				i=sep
+			///////////////
+			// 如果第一个字就超宽了,别循环了,会死循环
+			if i == 0 {
+				break
 			}
-			lines = append(lines, string(s[j:sep]))
-			sep = -1
+			//if sep == -1 {
+			//	if i == j {
+			//		i++
+			//	}
+			//	sep = i
+			//} else {
+			//	///////////////
+			//	//i = sep + 1
+			//	//////////////
+			//	i = sep
+			//}
+			i++
+			lines = append(lines, string(s[j:i]))
+			//sep = -1
 			j = i
 			l = 0
 		} else {