Skip to content

Commit f45a840

Browse files
authored
fix(mix_cw_font): 超长字符串导致堆栈溢出 (#91)
1 parent cf0252c commit f45a840

File tree

5 files changed

+31
-51
lines changed

5 files changed

+31
-51
lines changed

docs/mix_cw_font.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44

55
**Compatibility** : RTF 1.6 specification
66

7-
> [!Caution]
8-
>
9-
> - 若在已经使用 `%mix_cw_font` 处理后生成的 RTF 文件上再次使用此宏,则会发生堆栈溢出错误。
10-
> - 若某个单元格或段落中的字符数量超出 700(GBK)或 350(UTF8),则会发生堆栈溢出错误。
11-
127
## 语法
138

149
### 必选参数
@@ -132,7 +127,7 @@ wfont = Monoca
132127

133128
**Syntax** : `true` | `false`
134129

135-
指定是否删除宏程序运行产生的中间数据集
130+
指定是否删除宏程序运行产生的中间数据集
136131

137132
**Default** : `false`
138133

src/gb18030/mix_cw_font.sas

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
data _tmp_rtf_polish(compress = yes);
214214
set _tmp_rtf_font_added;
215215

216-
reg_header_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\{\\line\}/o");
216+
reg_header_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{([\x20-\x7e\x08-\x0d]+)\{\\line\}$/o");
217217

218218
length tmp_line $32767;
219219
retain tmp_line;
@@ -252,30 +252,25 @@
252252
length context_mixed $32767;
253253

254254
/*修改单元格文本字体*/
255-
reg_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\\cell\}/o");
256-
reg_cell_inside_id = prxparse("/\\animtext\d*\\ul\d*\\strike\d*\\b\d*\\i\d*\\f\d*\\fs\d*\\cf\d*((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)/o");
257-
reg_cell_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
255+
reg_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{([\x20-\x7e\x08-\x0d]+)\\cell\}/o");
256+
reg_cell_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
258257
if prxmatch(reg_cell_id, trim(line)) then do;
259258
call prxposn(reg_cell_id, 1, st, len);
260259
context_mixed = substr(trim(line), st, len);
261260

262-
if prxmatch(reg_cell_inside_id, trim(line)) then do; /*表头不止一行,需要进一步定位*/
263-
call prxposn(reg_cell_inside_id, 1, st, len);
264-
context_mixed = substr(trim(line), st, len);
265-
end;
266-
267261
/*修改字体*/
268262
call prxchange(reg_cell_change_font_id, -1, trim(context_mixed), context_mixed);
269263
if find(context_mixed, "\f&cfont_id") ^= 1 then do;
270264
context_mixed = "\f&wfont_id " || trim(context_mixed);
271265
end;
272-
266+
273267
line = substr(line, 1, st - 1) || trim(context_mixed) || substr(line, st + len);
268+
274269
end;
275-
270+
276271
/*修改标题文本字体*/
277-
reg_outllv_id = prxparse("/\\outlinelevel\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\}/o");
278-
reg_outlnlv_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
272+
reg_outllv_id = prxparse("/\\outlinelevel\d*\{([\x20-\x7e\x08-\x0d]+)\}/o");
273+
reg_outlnlv_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
279274

280275
if prxmatch(reg_outllv_id, trim(line)) then do;
281276
call prxposn(reg_outllv_id, 1, st, len);
@@ -291,8 +286,8 @@
291286
end;
292287

293288
/*修改脚注文本字体*/
294-
reg_ftnt_id = prxparse("/\\pard\\b\d*\\i\d*\\chcbpat\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{\}\\q[lcr]\\fs\d*((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\\cf\d*\\chcbpat\d*/o");
295-
reg_ftnt_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
289+
reg_ftnt_id = prxparse("/\\pard\\b\d*\\i\d*\\chcbpat\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{\}\\q[lcr]\\fs\d*([\x20-\x7e\x08-\x0d]+)\\cf\d*\\chcbpat\d*/o");
290+
reg_ftnt_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
296291

297292
if prxmatch(reg_ftnt_id, trim(line)) then do;
298293
call prxposn(reg_ftnt_id, 1, st, len);

src/gbk/mix_cw_font.sas

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
data _tmp_rtf_polish(compress = yes);
214214
set _tmp_rtf_font_added;
215215

216-
reg_header_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\{\\line\}/o");
216+
reg_header_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{([\x20-\x7e\x08-\x0d]+)\{\\line\}$/o");
217217

218218
length tmp_line $32767;
219219
retain tmp_line;
@@ -252,30 +252,25 @@
252252
length context_mixed $32767;
253253

254254
/*修改单元格文本字体*/
255-
reg_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\\cell\}/o");
256-
reg_cell_inside_id = prxparse("/\\animtext\d*\\ul\d*\\strike\d*\\b\d*\\i\d*\\f\d*\\fs\d*\\cf\d*((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)/o");
257-
reg_cell_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
255+
reg_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{([\x20-\x7e\x08-\x0d]+)\\cell\}/o");
256+
reg_cell_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
258257
if prxmatch(reg_cell_id, trim(line)) then do;
259258
call prxposn(reg_cell_id, 1, st, len);
260259
context_mixed = substr(trim(line), st, len);
261260

262-
if prxmatch(reg_cell_inside_id, trim(line)) then do; /*表头不止一行,需要进一步定位*/
263-
call prxposn(reg_cell_inside_id, 1, st, len);
264-
context_mixed = substr(trim(line), st, len);
265-
end;
266-
267261
/*修改字体*/
268262
call prxchange(reg_cell_change_font_id, -1, trim(context_mixed), context_mixed);
269263
if find(context_mixed, "\f&cfont_id") ^= 1 then do;
270264
context_mixed = "\f&wfont_id " || trim(context_mixed);
271265
end;
272-
266+
273267
line = substr(line, 1, st - 1) || trim(context_mixed) || substr(line, st + len);
268+
274269
end;
275-
270+
276271
/*修改标题文本字体*/
277-
reg_outllv_id = prxparse("/\\outlinelevel\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\}/o");
278-
reg_outlnlv_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
272+
reg_outllv_id = prxparse("/\\outlinelevel\d*\{([\x20-\x7e\x08-\x0d]+)\}/o");
273+
reg_outlnlv_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
279274

280275
if prxmatch(reg_outllv_id, trim(line)) then do;
281276
call prxposn(reg_outllv_id, 1, st, len);
@@ -291,8 +286,8 @@
291286
end;
292287

293288
/*修改脚注文本字体*/
294-
reg_ftnt_id = prxparse("/\\pard\\b\d*\\i\d*\\chcbpat\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{\}\\q[lcr]\\fs\d*((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\\cf\d*\\chcbpat\d*/o");
295-
reg_ftnt_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
289+
reg_ftnt_id = prxparse("/\\pard\\b\d*\\i\d*\\chcbpat\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{\}\\q[lcr]\\fs\d*([\x20-\x7e\x08-\x0d]+)\\cf\d*\\chcbpat\d*/o");
290+
reg_ftnt_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
296291

297292
if prxmatch(reg_ftnt_id, trim(line)) then do;
298293
call prxposn(reg_ftnt_id, 1, st, len);

src/utf16/mix_cw_font.sas

-920 Bytes
Binary file not shown.

src/utf8/mix_cw_font.sas

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
data _tmp_rtf_polish(compress = yes);
214214
set _tmp_rtf_font_added;
215215

216-
reg_header_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\{\\line\}/o");
216+
reg_header_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{([\x20-\x7e\x08-\x0d]+)\{\\line\}$/o");
217217

218218
length tmp_line $32767;
219219
retain tmp_line;
@@ -252,30 +252,25 @@
252252
length context_mixed $32767;
253253

254254
/*修改单元格文本字体*/
255-
reg_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\\cell\}/o");
256-
reg_cell_inside_id = prxparse("/\\animtext\d*\\ul\d*\\strike\d*\\b\d*\\i\d*\\f\d*\\fs\d*\\cf\d*((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)/o");
257-
reg_cell_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
255+
reg_cell_id = prxparse("/\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{([\x20-\x7e\x08-\x0d]+)\\cell\}/o");
256+
reg_cell_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
258257
if prxmatch(reg_cell_id, trim(line)) then do;
259258
call prxposn(reg_cell_id, 1, st, len);
260259
context_mixed = substr(trim(line), st, len);
261260

262-
if prxmatch(reg_cell_inside_id, trim(line)) then do; /*表头不止一行,需要进一步定位*/
263-
call prxposn(reg_cell_inside_id, 1, st, len);
264-
context_mixed = substr(trim(line), st, len);
265-
end;
266-
267261
/*修改字体*/
268262
call prxchange(reg_cell_change_font_id, -1, trim(context_mixed), context_mixed);
269263
if find(context_mixed, "\f&cfont_id") ^= 1 then do;
270264
context_mixed = "\f&wfont_id " || trim(context_mixed);
271265
end;
272-
266+
273267
line = substr(line, 1, st - 1) || trim(context_mixed) || substr(line, st + len);
268+
274269
end;
275-
270+
276271
/*修改标题文本字体*/
277-
reg_outllv_id = prxparse("/\\outlinelevel\d*\{((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\}/o");
278-
reg_outlnlv_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
272+
reg_outllv_id = prxparse("/\\outlinelevel\d*\{([\x20-\x7e\x08-\x0d]+)\}/o");
273+
reg_outlnlv_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
279274

280275
if prxmatch(reg_outllv_id, trim(line)) then do;
281276
call prxposn(reg_outllv_id, 1, st, len);
@@ -291,8 +286,8 @@
291286
end;
292287

293288
/*修改脚注文本字体*/
294-
reg_ftnt_id = prxparse("/\\pard\\b\d*\\i\d*\\chcbpat\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{\}\\q[lcr]\\fs\d*((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])+)\\cf\d*\\chcbpat\d*/o");
295-
reg_ftnt_change_font_id = prxparse("s/(?!<\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
289+
reg_ftnt_id = prxparse("/\\pard\\b\d*\\i\d*\\chcbpat\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{\}\\q[lcr]\\fs\d*([\x20-\x7e\x08-\x0d]+)\\cf\d*\\chcbpat\d*/o");
290+
reg_ftnt_change_font_id = prxparse("s/(?<!\\f&cfont_id )((?:\\\x27[0-9A-F]{2}|\\u\d{1,5};)+)/\\f&cfont_id $1\\f&wfont_id /o");
296291

297292
if prxmatch(reg_ftnt_id, trim(line)) then do;
298293
call prxposn(reg_ftnt_id, 1, st, len);

0 commit comments

Comments
 (0)